Casemiro scored first for the hosts before Messi leveled for Barcelona in the 33rd minute. Ivan Rakitic put the visitors in the lead in the 73rd minute.
Four minutes later, Sergio Ramos was shown a red card reducing Madrid to 10 men.
Substitute James Rodriguez thought he had earned Madrid a point late on when he scored in 85th minute.
But Messi, who scored his first with a superb jinking run and finish, fired in from the edge of the area to win it for Barcelona.
Both Messi and Cristiano Ronaldo had earlier missed good opportunities to give their sides the lead, with the Argentina international poking wide of an open goal before the break and the Real Madrid forward slicing over in the second half.
Real – who have a game in hand on Barcelona – also felt they should have had a penalty when Ronaldo was clipped by Samuel Umtiti after only two minutes.
Barca, whose win put them top because of a better head-to-head record, have five games left, Real have six to play.
Barcelona win sent to the top of La liga with Madridrid having a game in hand.
Both sides will be back in La Liga action on Wednesday, as Barcelona host the struggling Osasuna and Real Madrid visit Deportivo La Coruna who are currently 16th on the table.