Barcelona lost a home league match for the first time in two years as the Spanish champions were beaten by Real Betis's expert display at the Nou Camp.
Junior Firpo gave Betis a deserved lead after 20 minutes, before veteran Joaquin made it two before the break.
Lionel Messi scored a penalty in reply but a Marc-Andre ter Stegen error saw Giovani lo Celso add a third for Betis.
Arturo Vidal's tap-in gave Barca hope, but Sergio Canales got the away side's fourth, before a Messi consolation.
Ernesto Valverde's side remain at the top of La Liga, one point ahead of Sevilla, Atletico Madrid and Alaves.
The hosts had Ivan Rakitic sent off for a second yellow card with eight minutes left when trailing 3-2 and were powerless to match a determined and clinical Betis side, despite Messi's two goals on his return from a fractured arm suffered three weeks ago.
Barca's previous home league defeat came on 10 September 2016, when they lost 2-1 to Alaves.
Betis had lost on their past eight visits to the Nou Camp and had not won there for more than 20 years.
But they came away with three points that lifts them up to 12th in the table courtesy of an impressive display built on adventurous counter-attacking and smart play in possession.
Quique Setien's side went into this game having scored only eight goals in 11 matches, the lowest return in La Liga.
Here they mustered eight shots on goal to Barca's five and scored from half of those.
Ter Stegen did let a Lo Celso strike slip through his gloves immediately after Messi had scored Barca's first from the penalty spot, which slowed the home side's momentum.
But nothing should be taken away from Betis, who more than deserved this victory which keeps Barca's rivals for the title within touching distance.