diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index db29a87e94..5adce02347 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"io"
 	"os"
+	"reflect"
 	"runtime"
 	"strconv"
 	"sync/atomic"
@@ -56,6 +57,20 @@ The init command initializes a new genesis block and definition for the network.
 This is a destructive action and changes the network in which you will be
 participating.
 
+It expects the genesis file as argument.`,
+	}
+	updateCommand = cli.Command{
+		Action:    utils.MigrateFlags(updateTransitions),
+		Name:      "update",
+		Usage:     "Update genesis block with new transitions",
+		ArgsUsage: "<genesisPath>",
+		Flags: []cli.Flag{
+			utils.DataDirFlag,
+		},
+		Category: "BLOCKCHAIN COMMANDS",
+		Description: `
+The update commands updates the chain data configuration in genesis block for new transition changes.
+
 It expects the genesis file as argument.`,
 	}
 	dumpGenesisCommand = cli.Command{
@@ -206,6 +221,64 @@ func getIsQuorum(file io.Reader) bool {
 	return altGenesis.Config.IsQuorum == nil || *altGenesis.Config.IsQuorum
 }
 
+// updateTransitions will update genesis block with the new transitions data
+func updateTransitions(ctx *cli.Context) error {
+	// Open and initialise both full and light databases
+	stack, _ := makeConfigNode(ctx)
+	defer stack.Close()
+
+	// Make sure we have a valid genesis JSON
+	genesisPath := ctx.Args().First()
+	if len(genesisPath) == 0 {
+		utils.Fatalf("Must supply path to genesis JSON file")
+	}
+	file, err := os.Open(genesisPath)
+	if err != nil {
+		utils.Fatalf("Failed to read genesis file: %v", err)
+	}
+	defer file.Close()
+
+	genesis := new(core.Genesis)
+	if err := json.NewDecoder(file).Decode(genesis); err != nil {
+		utils.Fatalf("invalid genesis file: %v", err)
+	}
+
+	// Quorum
+	file.Seek(0, 0)
+	genesis.Config.IsQuorum = getIsQuorum(file)
+
+	if genesis.Config.IsQuorum {
+		err = genesis.Config.CheckTransitionsData()
+		if err != nil {
+			utils.Fatalf("transitions data invalid: %v", err)
+		}
+	} else {
+		return fmt.Errorf("update transitions only apply to quorum configuration")
+	}
+
+	// Update transitions and recommit to db
+	for _, name := range []string{"chaindata", "lightchaindata"} {
+		chaindb, err := stack.OpenDatabase(name, 0, 0, "", false)
+		if err != nil {
+			utils.Fatalf("Failed to open database: %v", err)
+		}
+		stored := rawdb.ReadCanonicalHash(chaindb, 0)
+		storedcfg := rawdb.ReadChainConfig(chaindb, stored)
+		if storedcfg == nil {
+			return fmt.Errorf("found genesis block without chain config")
+		}
+		// Check that new transitions have changed before updating them
+		if !reflect.DeepEqual(storedcfg.Transitions, genesis.Config.Transitions) {
+			log.Info("Change found in transitions, proceeding to update chain config")
+			storedcfg.Transitions = genesis.Config.Transitions
+			rawdb.WriteChainConfig(chaindb, stored, storedcfg)
+		} else {
+			log.Info("No change in transitions, no update required to chain config")
+		}
+	}
+	return nil
+}
+
 // initGenesis will initialise the given JSON format genesis file and writes it as
 // the zero'd block (i.e. genesis) or will fail hard if it can't succeed.
 func initGenesis(ctx *cli.Context) error {
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index f7a65e3e4e..003124a5a9 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -269,6 +269,7 @@ func init() {
 	app.Commands = []cli.Command{
 		// See chaincmd.go:
 		initCommand,
+		updateCommand,
 		mpsdbUpgradeCommand,
 		importCommand,
 		exportCommand,
diff --git a/go.mod b/go.mod
index ace412f412..3336c1e081 100644
--- a/go.mod
+++ b/go.mod
@@ -89,6 +89,7 @@ require (
 	golang.org/x/text v0.3.7
 	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
 	google.golang.org/grpc v1.46.0
+	google.golang.org/protobuf v1.28.0
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
 	gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951
 	gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce