Jack Grealish looked to have headed City to a crucial victory in their pursuit of Arsenal at the top of the Premier League when he came off the bench to head home on the hour at Old Trafford.
But United responded to claim a hotly-contested equaliser through Bruno Fernandes after Marcus Rashford was deemed by VAR not to be interfering with play despite racing towards the ball from an offside position.
City reacted furiously and failed to regroup after play restarted, allowing Rashford to poke home a winner from an Alejandro Garnacho cross eight minutes from time.
It was Rashford's eighth goal in his last seven appearances and lifted United to within a point of title-chasing City, whose recent indifferent spell after their midweek Carabao Cup exit continued.
The result means Arsenal can now move eight points clear at the summit if they win their own derby contest against Tottenham on Sunday.
The drama of the closing minutes was a far cry from the pedestrian nature of the first half, when City were sloppy in possession and unable to stamp their usual authority on the game.
That encouraged United and it was they who had the game's chance when Bernardo Silva lost possession and Fernandes shot wide from a Christian Eriksen pass.
United threatened again as Anthony Martial broke clear but his ball into the box took a ricochet and Joao Cancelo prevented the in-form Rashford from shooting.
City struggled to get their key forwards, notably Erling Haaland, into the game but the Norwegian but did get an opening as United failed to clear one attack, only for Casemiro to block his powerful strike.
That was a rare opportunity for City. As the first half wore on, United began to look the stronger but were unable to make the most of their attacks.
Rashford beat the outrushing Ederson on one break but was forced wide and Manuel Akanji blocked his shot. On another occasion Rashford was let down by a heavy touch and Ederson gathered.
United looked concerned when Rashford went down with what appeared a hip injury just before the interval but he was able to continue.
The half ended with Kyle Walker curling a speculative effort wide from distance.
City began to show more urgency after the break and the game opened up.
It still took a change from City to make the difference after Grealish replaced the ineffective Phil Foden after 57 minutes.
Moments later Grealish found himself in the right place as Kevin De Bruyne reached the byline and pulled back a cross for the England midfielder to head home from close range.
The real drama was still to come and United levelled on 78 minutes in controversial circumstances.
Rashford was clearly offside as he raced onto a long ball from Casemiro but he opted not to take a touch and Fernandes swept home.
City surrounded the officials in response but, after a delay for a VAR check, the goal was given.
United sensed their opportunity and Rashford did the damage after Garnacho delivered a low ball across goal at the second attempt.