City were two goals ahead on aggregate going into the 90th minute after Riyad Mahrez's strike had added to their 4-3 first-leg win last week.
And then Rodrygo happened.
The Brazilian substitute turned home Karim Benzema's left-wing ball from close range in the final minute - with Real's very first shot on target.
And 90 seconds later he levelled the tie with a header into the top corner after Marco Asensio flicked on Dani Carvajal's cross.
City, who thought they were going through to a second consecutive all-English Champions League final, were shell-shocked.
Both sides had chances to win the tie before the full-time whistle. Ederson denied Rodrygo a quick-fire hat-trick and then an unmarked Phil Foden fired over inside the box.
And so to extra time the game went - and it was Real who got the decisive goal in yet another classic Champions League tie.
Benzema beat Ruben Dias to a loose ball in the box and was brought down by the City defender. He stepped up to take the penalty himself and scored his 43rd goal of the season. There is no doubt it is the most important.
That sets up a repeat of the most memorable Champions League final of recent years, when Real beat Liverpool 3-1 in 2018.