Young forward Maxwell Cornet stroked Bruno Genesio’s men into a surprise early lead and Lyon deservedly made it two through Sergi Darder’s wonderfully-taken goal on the stroke of half-time.
Lucas Moura pulled one back for the runaway Ligue 1 leaders, but Lyon held on for a famous victory that moves them into the top three.
For PSG this was a first league loss since a 3-2 defeat at Bordeaux in March 2015, although they remain 23 points clear of AS Monaco at the top of the table.
Manager Laurent Blanc admitted that his side were off the pace and did not deserve to take anything from the game.
“We were too average, myself included,” he told Canal+. “Lyon were in a better state of mind. Were we not at our best? I don’t know, we must regroup.
“We expected a difficult game, but not as hard. I took off a player at half-time (Benjamin Stambouli), I could have made more changes,” he admitted.
Lyon manager Genesio wants his team’s display to help them kick on for the rest of the campaign.
“The game counts for three points, but of course beating PSG makes it more satisfying,” he said.
“What pleased me? The way we implented the plan, with the will to press them high. Certainly, we were up against one of the best teams in Europe, but we need to repeat this performance until the end of the season.”
PSG were looking to extend their record unbeaten league streak to 37 matches, but Lyon started the stronger at Parc OL and they forged ahead in the 13th minute.
Alexandre Lacazette picked out 19-year-old Cornet, who displayed good footwork to cut inside Gregory van der Wiel, before curling confidently into the far corner to grab his third Ligue 1 goal.
The visitors are not used to being behind and their frustration boiled over when Thiago Motta appeared to strike Jordan Ferri in the face, with the Italian fortunate to escape with just a yellow card.
On the day that Thiago Silva spoke of suffering a bout of depression in the aftermath of Brazil’s World Cup thrashing at the hands of Germany two years ago, he was embarrassed by Darder in first half injury-time.
Despite Rafael’s cross being slightly behind Darder, the Spanish midfielder flicked the ball over the head of centre-back Silva with his first touch, and coolly steered home past Kevin Trapp with his second.
With the unbeaten run close to coming to an end Blanc responded by sending on Javier Pastore for Benjamin Stambouli at the interval.
The substitute was instrumental in creating space in the Lyon penalty area as the away side pulled one back less than six minutes into the second period.
Pastore was crowded out by a group of home defenders, but the ball broke kindly for Brazilian Lucas, who bent his shot just inside the far post.
Lyon went straight up the other end and could have restored their two-goal cushion, only for Ferri to side-foot wide.
It was by far the busiest outing for Trapp since his move to Paris last summer and the German made an excellent point-blank save with his legs to keep out Rachid Ghezzal.
But last season’s runners-up closed out a fourth win in five games with ease to move into the third and final Champions League place and become the first team to beat PSG domestically in almost a year.
Monaco were held to a goalless draw by in-form Nantes as Caen reignited their unlikely Champions League push with a 2-1 win at Saint-Etienne.
Monaco are eight points clear in second but the six teams directly below are separated by just two points in the race for third place.
Meanwhile, Marseille's match away to Gazelec Ajaccio was postponed due to the inclement weather in Corsica.
Follow us on Twitter @NatSportUAE
Like us on Facebook at facebook.com/TheNationalSport