A wild eighth inning in which Perez completed a three-run Kansas City rally with an RBI single and the Mariners tied the score with consecutive home runs by Franklin Gutierrez and Michael Saunders sent the game into extra innings.
Gordon and Perez kept Kansas City in the game in the 10th by throwing out Kyle Seager at home from left field when Seager tried to score on a fly out. Perez, the Royals catcher, made a diving tag on Seager to end the threat.
Gordon opened the 12th with a four-pitch walk off reliever Lucas Luetge (1-3) and took second on the sacrifice. After another out Johnny Giavotella walked.
Perez pulled the next pitch into the left-corner, one-hopping the wall. Gordon scored easily. Giavotella was out at the plate on a strong relay play but the Royals still led.
That left Kansas City three games back of Cleveland in the race for an AL wild-card slot with Texas in between. The Royals have six games remaining.
Wade Davis (8-11) took the win with two innings of no-hit relief and Greg Holland got his 45th save despite walking the first two batters he faced in the bottom of the 12th. He also struck out the last two Mariners batters. He has tied the franchise record held by Dan Quisenberry and Jeff Montgomery for saves in a season.
Billy Butler staked Kansas City to the lead in the fourth with a two-run single but Seattle went ahead 3-2 with Abraham Almonte singling in Brad Miller in the sixth and Mike Zunino reaching on an error that got Saunders home and scoring himself on a Nick Franklin hit.