Pep Guardiola’s side were on an English top-flight record run of 21 successive wins in all competitions heading into the Manchester derby.
But United ruined City’s 28-game unbeaten run in all competitions thanks to an early penalty from Bruno Fernandes and Luke Shaw’s second-half strike at the Etihad Stadium.
Ole Gunnar Solskjaer’s team, unbeaten in their last 22 away league games, moved above Leicester into second place, but they are still 11 points behind City with 10 games left.
Despite surrendering their 15-match winning league run in their first defeat since losing at Tottenham in November, City remain firm favourites to lift the title for the third time in four seasons.
Barring a dramatic collapse from City in the closing weeks, United’s third win in the last four league meetings with their bitter rivals is likely to be remembered for cementing a top-four place rather than rekindling their title hopes.
United will be left to rue the recent slump that allowed City to pull so far ahead in the title race, but at least they slowed their neighbours’ march towards the trophy.
With just 34 seconds gone, Anthony Martial made a dangerous raid into the City area and Gabriel Jesus responded with a needless, clumsy challenge that sent the French striker sprawling.
Fernandes stepped up to take the penalty and squeezed his shot past Ederson, who got a hand on the ball but couldn’t keep it out.
It was United’s first goal in four games, putting City were behind for the first time in 20 league games.
Guardiola’s men gradually wrestled control and had a strong penalty appeal rejected by referee Anthony Taylor when Raheem Sterling was blocked by Fred.
Riyad Mahrez shot inches wide and Rodri’s drive hit the bar, but City were caught with a 50th minute sucker punch.
United left-back Shaw broke from deep inside his own half, played a one-two with Marcus Rashford and fired a fine finish past Ederson from just inside the area.
Liverpool crash again
Likely to be replaced by City as champions, Liverpool have now lost six consecutive home league games and gone eight without a win at Anfield after a 1-0 loss to Fulham.
That run is all the more remarkable as Jurgen Klopp’s men had gone nearly four years without a league defeat at home in 68 games between April 2017 and January this year.
Liverpool’s best chance of qualifying for next season’s Champions League may now be in winning the European Cup for a seventh time as they sit seventh, four points adrift of the top four, having played at least one game more than all their rivals.
Despite their lowly position in the table, Fulham had lost just one of their previous six games and were well worthy of a half-time lead.
Mohamed Salah’s surprise substitution in midweek provoked fresh speculation over the Egyptian’s future and he was at fault for the only goal in first-half stoppage time.
Mario Lemina outmuscled Salah to win the ball inside the Liverpool box before firing low across Alisson Becker into the far corner.
The hosts were far better after the break, but have not scored from open play at Anfield in seven games.
Alphonse Areola produced a stunning save to deny Diogo Jota before Sadio Mane came off the bench to hit the woodwork.
Fulham remain in the bottom three but only on goal difference behind Brighton.
Newcastle, one point above in the relegation zone, remain in deep trouble after a 0-0 draw at West Brom.
The Magpies had been unsettled by a dressing room bust-up between manager Steve Bruce and Matt Ritchie over the past week.
Mbaye Diagne missed Albion’s best chances to leave Sam Allardyce’s second-bottom side eight points from safety.
In the late game, Tottenham beat Crystal Palace 4-1 thanks to a brace each from Gareth Bale and Harry Kane.