Celta took a shock lead when Iago Aspas played in Fedor Smolov to score his first goal in Spanish football.
Toni Kroos then swept home from 16 yards and Sergio Ramos gave Real the lead with a penalty, which was won by Eden Hazard on his return after almost three months out with an ankle injury.
But Santi Mina scored a late equaliser from Denis Suarez’s pass.
Mina had only been on the pitch for two minutes when he scored the goal, which takes Celta out of the relegation zone on goal difference.
Real had the better chances, with Hazard lively on his return, Gareth Bale going close and Ramos having a goal disallowed.
But Celta stayed in the game and made Zinedine Zidane’s side pay with their late goal.
Real, who have only won one league title since 2012, are one point clear of Barca with 14 La Liga games remaining.