City controlled the majority of the game and were ahead early on after Raheem Sterling's 100th goal for the club.
Karim Benzema levelled before the half-hour but Gabriel Jesus' second-half strike sealed victory and a last eight tie with Lyon next Saturday.
After a tentative opening few minutes, City got a dream start with a goal after just nine minutes.
The high press paid immediate dividends when Raphael Varane dithered in possession to the right of Thibaut Courtois and Gabriel Jesus nicked the ball off his toes, passed to the unmarked Raheem Sterling who rolled the ball into the net despite a despairing lunge from a defender.
It was Sterling’s 100th goal for the Club and what a prestigious fixture to get it in.
Phil Foden and Sterling were both causing numerous problems every time City attacked and it wasn’t until the 21st minute that Ederson was called into action, turning a low drive from Karim Benzema and then again from Eden Hazard from the resulting corner.
But City’s two-goal aggregate lead only lasted until the 28th minute when Rodrygo skipped past Joao Cancelo on the right of the box before clipping in a fine cross that Karim Benzema leapt between Fernandinho and Rodrigo to nod past Ederson.
Suddenly, the visitors were back within just a goal of levelling the tie and cancelling out City’s hard-earned away goals advantage.
Neither side had a clear chance in the time that remained with the teams going in at the break level, but crucially still a goal ahead on aggregate.
City raced out of the blocks after the restart and a superb pass from Kevin De Bruyne setting Sterling free on the left but his shot was saved by Courtois.
Real Madrid continued to give possession away in their own half but City failed to make them pay again as Casemiro's poor pass was collected by Foden who played it to Ilkay Gundogan on the edge but the German's pass on to the unmarked Sterling was too heavy and Courtois was able to close down the opportunity.
But on 69 minutes, City finally did regain the lead and it was thanks to the hardworking Jesus who hounded Varane as he looked to deal with a long ball, gambled on a header back to Courtois and then clipped the ball past the Belgian from a tight angle.
It gave City breathing space as the clock ticked down and it was thoroughly deserved.
There were more chances in the time that remained and David Silva came on as a late sub - almost scoring another free-kick - as he played his last home game in a City shirt.
But City had done enough over the two legs and will head to Portugal in great spirits.
Sterling work, Raheem
In celebrating 100 goals for City, Raheem also became the first Englishman to reach three figures since Dennis Tueart, some 39 years ago.
He is also only the sixth English player to score 20 Champions League goals, with only Wayne Rooney reaching the target quicker.
It was also his 31st goal in all competitions – not a bad campaign!
Jesus work ethic is priceless
Gabriel Jesus was arguably the difference between the two teams over the two legs.
It was his equaliser in Madrid that drew City level and, perhaps even more crucially, it was Jesus that caused Sergio Ramos to be sent off as the defensive rock pulled the Brazilian down to prevent a third City goal.
It was a gamble and one that didn't pay off.
And in this leg, it was Jesus who robbed Varane to set up Sterling's opener and again when he forced Varane into another error to score City's second and effectively settle the tie.
Fantastic effort from the young Brazil striker who is proving the perfect team player.
What it means
City are into the Champions League quarter-finals for the fourth time.
City will now take on Lyon in Lisbon next Saturday.
Real Madrid: Courtois, Carvaja (Vazquez 83)l, F Mendy, Militao, Varane, Casemiro, Modric (Valverde 83), Kroos, Hazard (Jovic 83), Benzema, Rodrygo (Asensio 61)
Unused subs: Areola, Nacho, Marcelo, Díaz, Isco, Vinícius Júnior, ltube, Hernández