Gustafsson began playing hockey in Nynäshamns IF, before moving to Djurgårdens IF's youth organisation. Gustafsson represented team Stockholm in the 2008 TV-pucken, a national junior tournament, scoring four assists. He played the 2008–09 season with Djurgården's under-18 team. In the following season, Gustafsson played for both the under-18 team and the J20-team. For the 2010–11 season, Gustafsson had a permanent place in the J20-team which won their division and ended up third in the playoffs. He extended his contract with Djurgårdens IF in May 2011 through to the 2013–14 season. Gustafsson was called to make his Elitserien debut in the 2011–12 season opener against HV71 on 15 September 2011, but did not receive any game-time. In his second game, against Brynäs IF on 27 September 2011, he made his on-ice debut, playing six minutes of the game. Gustafsson scored his first Elitserien goal on 26 December 2011 against Fredrik Norrena of Linköpings HC. On June 23, 2012, at the 2012 NHL Entry Draft, Gustafsson was selected in the fourth round, 93rd overall by the Edmonton Oilers. On 4 April 2013, with Djurgårdens IF demoted to the second-tier HockeyAllsvenskan, Gustafsson left the team to sign a contract with SHL club Frölunda HC. After two successful seasons establishing himself with Frölunda, and with his NHL playing rights not retained by Edmonton, on 30 April 2015, Gustafsson signed a two-year contract with the Chicago Blackhawks. Gustafsson began the 2017–18 season with Chicago's American Hockey League affiliate, the Rockford IceHogs, but was recalled to the NHL on 9 January 2018. He recorded his first NHL goal and added an assist in a 7–3 loss to the New York Islanders on 20 January. On 6 March, Gustafsson signed a two-year contract extension with Chicago. In the 2019–20 season, Gustafsson entering the final season of his contract was unable to keep his scoring pace from the previous season. Adding 6 goals and 26 points in 59 games and with the Blackhawks out of contention for a playoff berth, Gustafsson was dealt by Chicago at the NHL trade deadline to the Calgary Flames in exchange for a 2020 third-round pick on 24 February 2020.