The sides went in level 2-2 at half-time as a record 19th goal against Madrid from Messi cancelled out Karim Benzema’s double after Andres Iniesta had put Barca in front.
Cristiano Ronaldo then put Madrid back in front from the penalty spot, but the hosts were reduced to 10-men when Sergio Ramos pulled down Neymar inside the box 10 minutes later and Messi levelled once more from the spot.
And the Argentine won the game with another penalty seven minutes from time after Iniesta had been felled by Xabi Alonso.
A first defeat for Real in 32 games means Atletico Madrid remain top of the table thanks to their better head-to-head record against Los Blancos with Barca still in third.
“The league starts a new now,” said Barca boss Gerardo Martino.
“More than the mathematical distance we were behind, the impression was people wrote us off. Atletico Madrid were always in the fight and I think that after this result we are too.
“We knew if we didn’t win tonight it was over for us. We still don’t have matters in our own hands, but we’ll now fight till the end.”
Real coach Carlo Ancelotti, meanwhile, lamented Ramos’ game-changing red card when Madrid had just gotten themselves back in front.
“I haven’t seen it again and it is difficult for me to comment on the decisions of the referee because there were many.
“However, it was the key moment. We were winning 3-2 and controlling the game well, but it is much more difficult to control the game with a player less.”
The game got off to a blistering start as after Neymar and Benzema had early efforts easily saved, Barca opened the scoring when Messi played in Iniesta behind the Real defence and the Spanish international smashed the ball in off the underside of the bar.
Benzema had a great chance to equalise five minutes later when he spooned Angel Di Maria’s cut-back over after a great a jinking run from the Argentine had taken him past three Barca defenders.
Messi could then have made it 2-0 when he fired wide with the type of opening he is normally deadly with as he raced onto Cesc Fabregas’ fine through ball.
Benzema made amends for his earlier miss 20 minutes in when Victor Valdes just failed to keep out his header from Di Maria’s cross.
The Frenchman then completed a rapid turnaround for the hosts as Javier Mascherano misjudged another Di Maria centre from the left and Benzema took a touch before firing past the helpless Valdes.
Gerard Pique had to make a vital clearance off the line to prevent a hat-trick of Di Maria assists for Benzema.
Barca responded before half-time and were level when Messi controlled a loose ball inside the area and slotted home at Diego Lopez’s near post.
Benzema could still have put Madrid in front at the break as his looping header from Dani Carvajal’s cross crept inches past the post.
The first opportunity of the second period also fell to Benzema after a terrific run and pass from Gareth Bale, but this time Valdes managed to make the save low to his right.
Carlo Ancelotti’s men did retake the lead on 55 minutes when referee Alberto Undiano Mallenco controversially awarded a penalty for a trip on Ronaldo by Alves despite the contact appearing to take place outside the area.
Ronaldo was unmoved, though, as he got up to take hammer the resulting spot-kick low past Valdes’ outstretched right hand.
However, the game turned again 25 minutes from time when Messi released Neymar and he was brought down by Ramos.
Real’s captain for the evening was shown his 19th red card for Los Blancos for denying a clear goalscoring opportunity and Messi converted from the spot to make it 3-3.
Alves then struck the inside of the post from 25 yards as Barca went in search of the goal that would salvage their title chances.
And they got it when Mallenco awarded a third penalty of the evening as Iniesta tumbled inside the area and Messi again dispatched it perfectly high past Lopez.