Lille claimed a narrow away victory at Angers to finish one point ahead of Paris St-Germain and clinch their fourth Ligue 1 title.
Jonathan David netted an early goal and Burak Yılmaz doubled Lille’s lead from the spot on the stroke of half-time.
Paris St-Germain beat Brest 2-0 but failed to lift the crown for only the second time in nine years.
Monaco, who drew 0-0 with Lens, took the final Champions League spot after Lyon lost 3-2 to Nice.
Lyon will be in next season’s Europa League while Marseille and Rennes qualify for the Europa Conference League.
Nantes are set for a relegation play-off with Toulouse in four days’ time after losing 2-1 at home to Montpellier.
Outsiders do it again
Despite their underdog tag, Lille have been here before.
In 2010/11 a squad that included Eden Hazard and Gervinho helped the northern France side lift their third Ligue 1 title and their first league crown in 57 years.
This season they’ve relied on 21-year-old Canada forward David and 35-year-old Turkey striker Yilmaz.
And it was David who settled any early nerves, latching on to a Renato Sanchez pass and side-footing Lille into the lead inside 10 minutes.
On the stroke of half-time David was caught by goalkeeper Paul Bernardoni in the penalty area with Lille player of the season Yilmaz finding the corner from 12 yards.
Lille may have been without captain and former Southampton defender Jose Fonte through suspension, but they were rarely threatened in the second half, with Fulgini’s late header the only negative in an otherwise perfect performance.
What now for Poch?
PSG had lifted seven of the last eight Ligue 1 titles, but Mauricio Pochettino’s side missed out on the crown for the first time since finishing runners-up to Monaco in 2016-17.
Despite winning both the French Cup and the Trophee des Champions since the former Tottenham manager took the helm in January, eight defeats in the league – including five at home – have led to an ultimately disappointing league campaign.
Away to out-of-form Brest, the nine-time Ligue 1 winners were awarded an early penalty when Angel di Maria was brought down in the box, only for Brazil forward Neymar to fail to hit the target from the spot.
They did open the scoring when a Di Maria corner deflected in off Brest midfielder Romain Faivre midway through the first period.
And the Argentine played through Kylian Mbappe, who rounded the keeper late on to net his 27th goal of the season and finish as the division’s top scorer.
PSG’s victory was redundant in the light of Lille’s win though and, given the extent of the Paris club’s spending, any season that they don’t claim their national title – never mind their ultimate aim of the Champions League – has to be viewed as a failure.