Artem Dovbyk and Miguel Gutierrez both scored for Girona in the first half, either side of Robert Lewandowski's equaliser, before Girona's Valery Fernandez and Cristhian Stuani sealed the victory after the break.
Girona, who remain unbeaten away from home in LaLiga this season, top the standings with 41 points from 16 games, having leapfrogged Real Madrid on 39 points after Carlo Ancelotti's side were held to a 1-1 draw by Real Betis on Saturday.
Barcelona, whose only previous defeat this season was to rivals Real at the end of October, are fourth on 34 points, level with third-placed Atletico Madrid who have a game in hand.
Barcelona fired off 31 shots, 11 of which were on target, but Girona's ex-Tottenham goalkeeper Paulo Gazzaniga pulled off a string of saves while the leaders scored with four out of their seven shots on target.
Take a bow Miguel Gutiérrez! 🤯
Girona take the lead against Barcelona yet again thanks to a stunner 🔴⚪ pic.twitter.com/vPHWd2Cbzu
— Viaplay Sports UK (@ViaplaySportsUK) December 10, 2023
Dovbyk put Girona in front in the 12th minute with a shot that bounced in off the bottom of the post for his eighth goal in his debut LaLiga season.
Lewandowski then rediscovered his goalscoring touch and equalised for the hosts seven minutes later, heading home following a corner. It was the Poland striker's first goal for Barcelona in nearly a month.
Gutierrez restored Girona's lead before half-time, after the defender broke into the box and netted a fine individual effort, and Fernandez made it 3-1 in the 80th minute with a low shot two minutes after coming off the bench.
"It is a tough defeat, we have not been good," Barcelona midfielder Frenkie de Jong told DAZN. "Girona did well, but it is our fault.
"We haven't been good with the ball, neither have I, especially in the first half.
"We are seven points behind Girona, which is a lot. There is time, there is a lot of LaLiga left, but we have to improve a lot. We are disappointed, it is hard, but we can come back."
Additional reporting by Reuters