Match ends, Lyon 2, Manchester City 2.
Pep Guardiola says Lyon were "one of the toughest teams" Manchester City have ever faced after the teams shared a 2-2 draw in France.
Lyon twice took second-half leads before City rescued a 2-2 draw which ensures qualification for the last 16 with one game to spare.
The French side wasted several clear-cut chances before Maxwel Cornet rifled in an angled drive to give them an early second-half lead.
City defender Aymeric Laporte quickly levelled with a header but Cornet fired in again to put Lyon on top of Group F.
However, Sergio Aguero reacted quickest to flick in a header two minutes later to ensure City remain in pole position to top the group.
"We are so delighted and so happy," Guardiola said. "It is a big compliment for the team.
"We played one of toughest teams we've ever faced. They are physical, strong, they counter-attack incredible.
"We reacted after 1-0 and 2-1 and we are in the final stages. This was our target.
"Now we must try to get a point to finish first in the group stage, but it is so important to go through."
- Relive Tuesday night's Champions League games
- Champions League permutations: Who needs what?
- Listen: Football Daily podcast after dramatic Champions League night
Why Aguero equaliser is so important to City
Even without the point, Guardiola's side would still have clinched their place in the knockout stage for the sixth successive season after Shakhtar Donetsk snatched a late 3-2 victory at Hoffenheim.
But it meant City know a draw in their final game against the already-eliminated German side will be enough to progress as group winners.
Finishing top would ensure City will not be drawn against another group winner - with the likes of Real Madrid, Bayern Munich and Juventus currently topping their groups - in the last 16.
Lyon looked set to join City in qualifying for the knockout stage with the draw, until Shakhtar's late winner in another breathless finish.
The French side still need a point in their final game against Shakhtar in Ukraine to progress.
Substance over style for City
Premier League leaders City have swept aside almost everything put in front of them domestically this season, but were given another tough test by a Lyon team which had been the only one to beat them in their previous 26 matches.
The French side, who are second in Ligue 1 but 15 points adrift of leaders Paris St-Germain, won 2-1 at Etihad Stadium in the opening group game back in September.
Again they caused City problems with their pace and power in the attacking third, with former Manchester United forward Memphis Depay and Cornet - who also scored in the reverse fixture - at the heart of their most potent play.
City have only conceded five goals in 13 Premier League matches this season, but Lyon have shown they can be vulnerable after scoring four against them in 180 minutes.
While City were uncharacteristically opened up at the back, they showed characteristics of a great side which they have not had to show too often under Pep Guardiola: the resilience to fight back from behind.
City lacked their usual attacking rhythm - more down to Lyon's intensity than a lack of their own - but showed their quality at set-pieces through Laporte and Aguero to earn a hard-fought draw.
"Lyon have good players in good areas and quick players but we got a good draw," City defender Kyle Walker said.
"That shows the character and belief in the dressing room. Important players come good at the right time."
Man of the match - Aymeric Laporte (Man City)
French centre-back Laporte is the only outfield player to have played every minute in the Premier League for Manchester City this season, and again he illustrated his importance to Guardiola's side with another commanding display.
The 24-year-old reads the game wonderfully and came to City's rescue in the first half on a couple of occasions, notably when he blocked a golden chance for Cornet.
While Laporte could do little to stop Cornet eventually opening the scoring, he dragged City back into the match when he was perfectly placed at the other end to steer in a header from Raheem Sterling's free-kick.
That gave City renewed confidence, perhaps also adding to their belief they could fight back for a second time in a dramatic conclusion to the game.
The only mystifying thing about Laporte's performance is how he continues to be overlooked by France and still without international recognition.
City in familiar territory of the last 16 - the stats
- After failing to get out of the group in their first two Champions League campaigns, Man City have reached the knockout stage in each of the last six seasons.
- Lyon are unbeaten in their first five group-stage games in the Champions League for the first time since 2008-09.
- Sergio Aguero has scored in each of his last six Champions League away appearances - only Cristiano Ronaldo (12) has a longer scoring streak on the road.
- Maxwel Cornet has scored in both of his Champions League appearances versus Manchester City (3 goals).
- David Silva has provided more assists for Man City in the Champions League than any other player (9).
Back to the Premier League for City, who are aiming to extend their two-point lead at the top when they host Bournemouth on Saturday (15:00 GMT).
That final Champions League group game against Hoffenheim, who are already eliminated, takes place at Etihad Stadium on 12 December.
- 6Guedes Filho
- 4Pereira da SilvaSubstituted forTeteat 74'minutes
- 22MendyBooked at 62mins
- 27CornetSubstituted forTerrierat 89'minutes
- 18FekirSubstituted forTraoréat 84'minutes
- 24Diop Gueye
- 7SterlingBooked at 34mins
- 25FernandinhoBooked at 23mins
- 10AgüeroSubstituted forFodenat 90+1'minutes
- 19SanéSubstituted forDelphat 71'minutes
- Gianluca Rocchi
- Shots on Target
Second Half ends, Lyon 2, Manchester City 2.
Substitution, Manchester City. Phil Foden replaces Sergio Agüero.
Offside, Manchester City. Fabian Delph tries a through ball, but Sergio Agüero is caught offside.
Substitution, Lyon. Martin Terrier replaces Maxwel Cornet.
Attempt blocked. Fernandinho (Manchester City) right footed shot from outside the box is blocked.
Corner, Manchester City. Conceded by Marcelo.
Fernandinho (Manchester City) wins a free kick in the defensive half.
Foul by Bertrand Traoré (Lyon).
Corner, Manchester City. Conceded by Jason Denayer.
Attempt blocked. Sergio Agüero (Manchester City) right footed shot from outside the box is blocked. Assisted by Raheem Sterling.
Substitution, Lyon. Bertrand Traoré replaces Nabil Fekir.
Goal! Lyon 2, Manchester City 2. Sergio Agüero (Manchester City) header from the centre of the box to the bottom left corner. Assisted by Riyad Mahrez with a cross following a corner.
Corner, Manchester City. Conceded by Marçal.
Attempt blocked. Fabian Delph (Manchester City) left footed shot from the left side of the box is blocked. Assisted by Sergio Agüero.
Goal! Lyon 2, Manchester City 1. Maxwel Cornet (Lyon) left footed shot from the centre of the box to the centre of the goal. Assisted by Memphis Depay with a through ball.
Foul by David Silva (Manchester City).
Tanguy NDombele (Lyon) wins a free kick in the attacking half.
Attempt saved. Maxwel Cornet (Lyon) left footed shot from the centre of the box is saved in the bottom left corner. Assisted by Memphis Depay.
Substitution, Lyon. Kenny Tete replaces Rafael.