diff --git a/arduino/cores/cores.go b/arduino/cores/cores.go
index 3201112d50b..69669efff4b 100644
--- a/arduino/cores/cores.go
+++ b/arduino/cores/cores.go
@@ -63,6 +63,7 @@ type PlatformRelease struct {
 	Platform                *Platform                     `json:"-"`
 	Properties              *properties.Map               `json:"-"`
 	Boards                  map[string]*Board             `json:"-"`
+	orderedBoards           []*Board                      `json:"-"` // The Boards of this platform, in the order they are defined in the boards.txt file.
 	Programmers             map[string]*Programmer        `json:"-"`
 	Menus                   *properties.Map               `json:"-"`
 	InstallDir              *paths.Path                   `json:"-"`
@@ -292,9 +293,16 @@ func (release *PlatformRelease) GetOrCreateBoard(boardID string) *Board {
 		PlatformRelease: release,
 	}
 	release.Boards[boardID] = board
+	release.orderedBoards = append(release.orderedBoards, board)
 	return board
 }
 
+// GetBoards returns the boards in this platforms in the order they
+// are defined in the platform.txt file.
+func (release *PlatformRelease) GetBoards() []*Board {
+	return release.orderedBoards
+}
+
 // RequiresToolRelease returns true if the PlatformRelease requires the
 // toolReleased passed as parameter
 func (release *PlatformRelease) RequiresToolRelease(toolRelease *ToolRelease) bool {
diff --git a/arduino/cores/packagemanager/loader.go b/arduino/cores/packagemanager/loader.go
index 75d04d9ecdb..298669186fb 100644
--- a/arduino/cores/packagemanager/loader.go
+++ b/arduino/cores/packagemanager/loader.go
@@ -470,18 +470,15 @@ func (pm *Builder) loadBoards(platform *cores.PlatformRelease) error {
 		return err
 	}
 
-	propertiesByBoard := boardsProperties.FirstLevelOf()
+	platform.Menus = boardsProperties.SubTree("menu")
 
-	if menus, ok := propertiesByBoard["menu"]; ok {
-		platform.Menus = menus
-	} else {
-		platform.Menus = properties.NewMap()
-	}
-	// This is not a board id so we remove it to correctly
-	// set all other boards properties
-	delete(propertiesByBoard, "menu")
-
-	for boardID, boardProperties := range propertiesByBoard {
+	// Build to boards structure following the boards.txt board ordering
+	for _, boardID := range boardsProperties.FirstLevelKeys() {
+		if boardID == "menu" {
+			// This is not a board id so we remove it to correctly set all other boards properties
+			continue
+		}
+		boardProperties := boardsProperties.SubTree(boardID)
 		var board *cores.Board
 		if !platform.PluggableDiscoveryAware {
 			convertVidPidIdentificationPropertiesToPluggableDiscovery(boardProperties)
diff --git a/arduino/cores/packagemanager/package_manager_test.go b/arduino/cores/packagemanager/package_manager_test.go
index 05a18e5ce72..580311d3225 100644
--- a/arduino/cores/packagemanager/package_manager_test.go
+++ b/arduino/cores/packagemanager/package_manager_test.go
@@ -218,6 +218,56 @@ func TestBoardOptionsFunctions(t *testing.T) {
 	}
 }
 
+func TestBoardOrdering(t *testing.T) {
+	pmb := packagemanager.NewBuilder(dataDir1, dataDir1.Join("packages"), nil, nil, "")
+	_ = pmb.LoadHardwareFromDirectories(paths.NewPathList(dataDir1.Join("packages").String()))
+	pm := pmb.Build()
+	pme, release := pm.NewExplorer()
+	defer release()
+
+	pl := pme.FindPlatform(&packagemanager.PlatformReference{
+		Package:              "arduino",
+		PlatformArchitecture: "avr",
+	})
+	require.NotNil(t, pl)
+	plReleases := pl.GetAllInstalled()
+	require.NotEmpty(t, plReleases)
+	avr := plReleases[0]
+	res := []string{}
+	for _, board := range avr.GetBoards() {
+		res = append(res, board.Name())
+	}
+	expected := []string{
+		"Arduino Yún",
+		"Arduino Uno",
+		"Arduino Duemilanove or Diecimila",
+		"Arduino Nano",
+		"Arduino Mega or Mega 2560",
+		"Arduino Mega ADK",
+		"Arduino Leonardo",
+		"Arduino Leonardo ETH",
+		"Arduino Micro",
+		"Arduino Esplora",
+		"Arduino Mini",
+		"Arduino Ethernet",
+		"Arduino Fio",
+		"Arduino BT",
+		"LilyPad Arduino USB",
+		"LilyPad Arduino",
+		"Arduino Pro or Pro Mini",
+		"Arduino NG or older",
+		"Arduino Robot Control",
+		"Arduino Robot Motor",
+		"Arduino Gemma",
+		"Adafruit Circuit Playground",
+		"Arduino Yún Mini",
+		"Arduino Industrial 101",
+		"Linino One",
+		"Arduino Uno WiFi",
+	}
+	require.Equal(t, expected, res)
+}
+
 func TestFindToolsRequiredForBoard(t *testing.T) {
 	os.Setenv("ARDUINO_DATA_DIR", dataDir1.String())
 	configuration.Settings = configuration.Init("")
diff --git a/commands/board/listall.go b/commands/board/listall.go
index d18784f9581..78f945ea864 100644
--- a/commands/board/listall.go
+++ b/commands/board/listall.go
@@ -70,7 +70,7 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListA
 				targetPackage.Maintainer,
 			}
 
-			for _, board := range installedPlatformRelease.Boards {
+			for _, board := range installedPlatformRelease.GetBoards() {
 				if !req.GetIncludeHiddenBoards() && board.IsHidden() {
 					continue
 				}
diff --git a/internal/integrationtest/board/board_list_test.go b/internal/integrationtest/board/board_list_test.go
new file mode 100644
index 00000000000..12b60497171
--- /dev/null
+++ b/internal/integrationtest/board/board_list_test.go
@@ -0,0 +1,63 @@
+// This file is part of arduino-cli.
+//
+// Copyright 2022 ARDUINO SA (http://www.arduino.cc/)
+//
+// This software is released under the GNU General Public License version 3,
+// which covers the main part of arduino-cli.
+// The terms of this license can be found at:
+// https://www.gnu.org/licenses/gpl-3.0.en.html
+//
+// You can be released from the requirements of the above licenses by purchasing
+// a commercial license. Buying such a license is mandatory if you want to
+// modify or otherwise use the software for commercial activities involving the
+// Arduino software without disclosing the source code of your own applications.
+// To purchase a commercial license, send an email to license@arduino.cc.
+
+package board_test
+
+import (
+	"testing"
+
+	"github.com/arduino/arduino-cli/internal/integrationtest"
+	"github.com/stretchr/testify/require"
+	"go.bug.st/testifyjson/requirejson"
+)
+
+func TestCorrectBoardListOrdering(t *testing.T) {
+	env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
+	defer env.CleanUp()
+
+	_, _, err := cli.Run("core", "install", "arduino:avr")
+	require.NoError(t, err)
+	jsonOut, _, err := cli.Run("board", "listall", "--format", "json")
+	require.NoError(t, err)
+	requirejson.Query(t, jsonOut, "[.boards[] | .fqbn]", `[
+		"arduino:avr:yun",
+		"arduino:avr:uno",
+		"arduino:avr:unomini",
+		"arduino:avr:diecimila",
+		"arduino:avr:nano",
+		"arduino:avr:mega",
+		"arduino:avr:megaADK",
+		"arduino:avr:leonardo",
+		"arduino:avr:leonardoeth",
+		"arduino:avr:micro",
+		"arduino:avr:esplora",
+		"arduino:avr:mini",
+		"arduino:avr:ethernet",
+		"arduino:avr:fio",
+		"arduino:avr:bt",
+		"arduino:avr:LilyPadUSB",
+		"arduino:avr:lilypad",
+		"arduino:avr:pro",
+		"arduino:avr:atmegang",
+		"arduino:avr:robotControl",
+		"arduino:avr:robotMotor",
+		"arduino:avr:gemma",
+		"arduino:avr:circuitplay32u4cat",
+		"arduino:avr:yunmini",
+		"arduino:avr:chiwawa",
+		"arduino:avr:one",
+		"arduino:avr:unowifi"
+	]`)
+}