diff --git a/internal/pkg/commands/log.go b/internal/pkg/commands/log.go
index 036abdc..6f59b9f 100644
--- a/internal/pkg/commands/log.go
+++ b/internal/pkg/commands/log.go
@@ -36,10 +36,11 @@
 )
 
 const (
-	defaultComponentName = "global"
-	defaultPackageName   = "default"
-	logPackagesListKey   = "log_package_list" // kvstore key containing list of allowed log packages
-	logTracingStatusKey  = "trace_publish"
+	defaultComponentName    = "global"
+	defaultPackageName      = "default"
+	logPackagesListKey      = "log_package_list" // kvstore key containing list of allowed log packages
+	logTracingStatusKey     = "trace_publish"
+	logCorrelationStatusKey = "log_correlation"
 )
 
 // Custom Option representing <component-name>#<package-name> format (package is optional)
@@ -121,6 +122,30 @@
 	} `positional-args:"yes" required:"yes"`
 }
 
+// EnableLogCorrelationOpts represent the supported CLI arguments for the log correlation enable command
+type EnableLogCorrelationOpts struct {
+	OutputOptions
+	Args struct {
+		Component []ComponentName
+	} `positional-args:"yes" required:"yes"`
+}
+
+// DisableLogCorrelationOpts represent the supported CLI arguments for the log correlation disable command
+type DisableLogCorrelationOpts struct {
+	OutputOptions
+	Args struct {
+		Component []ComponentName
+	} `positional-args:"yes" required:"yes"`
+}
+
+// ListLogCorrelationOpts represents the supported CLI arguments for the log correlation list command
+type ListLogCorrelationOpts struct {
+	ListOutputOptions
+	Args struct {
+		Component []ComponentName
+	} `positional-args:"yes" required:"yes"`
+}
+
 // LogPackageOpts represents the log package commands
 type LogPackageOpts struct {
 	ListLogPackages ListLogPackagesOpts `command:"list"`
@@ -140,11 +165,19 @@
 	ListLogTracing    ListLogTracingOpts    `command:"list"`
 }
 
+// LogCorrelationOpts represents the log correlation commands
+type LogCorrelationOpts struct {
+	EnableLogCorrelation  EnableLogCorrelationOpts  `command:"enable"`
+	DisableLogCorrelation DisableLogCorrelationOpts `command:"disable"`
+	ListLogCorrelation    ListLogCorrelationOpts    `command:"list"`
+}
+
 // LogOpts represents the log commands
 type LogOpts struct {
-	LogLevel   LogLevelOpts   `command:"level"`
-	LogPackage LogPackageOpts `command:"package"`
-	LogTracing LogTracingOpts `command:"tracing"`
+	LogLevel       LogLevelOpts       `command:"level"`
+	LogPackage     LogPackageOpts     `command:"package"`
+	LogTracing     LogTracingOpts     `command:"tracing"`
+	LogCorrelation LogCorrelationOpts `command:"correlation"`
 }
 
 var logOpts = LogOpts{}
@@ -236,7 +269,6 @@
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
-
 	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
 	defer cancel()
 
@@ -357,7 +389,6 @@
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
-
 	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
 	defer cancel()
 
@@ -642,7 +673,6 @@
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
-
 	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
 	defer cancel()
 
@@ -823,7 +853,6 @@
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
-
 	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
 	defer cancel()
 
@@ -897,12 +926,6 @@
 // Omitting the component name will enable trace publishing for all the components, as shown in below command.
 // voltctl log tracing enable
 func (options *EnableLogTracingOpts) Execute(args []string) error {
-
-	var (
-		componentNames []string
-		err            error
-	)
-
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
@@ -917,6 +940,7 @@
 	defer cleanupFunc()
 
 	var output []LogLevelOutput
+	var componentNames []string
 
 	if len(options.Args.Component) == 0 {
 		// Apply to all components if no specific component has been indicated
@@ -940,24 +964,23 @@
 		err := config.Save(ctx, logTracingStatusKey, "ENABLED")
 		if err != nil {
 			output = append(output, LogLevelOutput{ComponentName: component, Status: "Failure", Error: err.Error()})
-		} else {
-			outmsg := ""
-			cvalid := false
-			for _, cname := range validComponents {
-				if component == cname {
-					cvalid = true
-					break
-				}
-			}
-
-			// For invalid component, add * against its name to indicate possible mis-configuration
-			if !cvalid {
-				component = "*" + component
-				outmsg = "Entered Component Name is not Currently active in Voltha"
-			}
-
-			output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
+			continue
 		}
+		outmsg := ""
+		cvalid := false
+		for _, cname := range validComponents {
+			if component == cname {
+				cvalid = true
+				break
+			}
+		}
+
+		// For invalid component, add * against its name to indicate possible mis-configuration
+		if !cvalid {
+			component = "*" + component
+			outmsg = "Entered Component Name is not Currently active in Voltha"
+		}
+		output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
 	}
 
 	outputFormat := CharReplacer.Replace(options.Format)
@@ -982,12 +1005,6 @@
 // Omitting the component name will disable trace publishing for all the components, as shown in below command.
 // voltctl log tracing disable
 func (options *DisableLogTracingOpts) Execute(args []string) error {
-
-	var (
-		componentNames []string
-		err            error
-	)
-
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
@@ -1002,6 +1019,7 @@
 	defer cleanupFunc()
 
 	var output []LogLevelOutput
+	var componentNames []string
 
 	if len(options.Args.Component) == 0 {
 		// Apply to all components if no specific component has been indicated
@@ -1026,24 +1044,24 @@
 
 		if err != nil {
 			output = append(output, LogLevelOutput{ComponentName: component, Status: "Failure", Error: err.Error()})
-		} else {
-			outmsg := ""
-			cvalid := false
-			for _, cname := range validComponents {
-				if component == cname {
-					cvalid = true
-					break
-				}
-			}
-
-			// For invalid component, add * against its name to indicate possible mis-configuration
-			if !cvalid {
-				component = "*" + component
-				outmsg = "Entered Component Name is not Currently active in Voltha"
-			}
-
-			output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
+			continue
 		}
+		outmsg := ""
+		cvalid := false
+		for _, cname := range validComponents {
+			if component == cname {
+				cvalid = true
+				break
+			}
+		}
+
+		// For invalid component, add * against its name to indicate possible mis-configuration
+		if !cvalid {
+			component = "*" + component
+			outmsg = "Entered Component Name is not Currently active in Voltha"
+		}
+
+		output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
 	}
 
 	outputFormat := CharReplacer.Replace(options.Format)
@@ -1068,13 +1086,6 @@
 // Omitting the component name will list trace publishing for all the components, as shown in below command.
 // voltctl log tracing list
 func (options *ListLogTracingOpts) Execute(args []string) error {
-
-	var (
-		data           []model.LogFeature = []model.LogFeature{}
-		componentNames []string
-		err            error
-	)
-
 	ProcessGlobalOptions()
 
 	log.SetAllLogLevel(log.FatalLevel)
@@ -1088,6 +1099,7 @@
 	}
 	defer cleanupFunc()
 
+	var componentNames []string
 	if len(options.Args.Component) == 0 {
 		// Apply to all components if no specific component has been indicated
 		componentNames, err = cm.RetrieveComponentList(ctx, config.ConfigTypeLogFeatures)
@@ -1102,6 +1114,7 @@
 	}
 
 	validComponents := getVolthaComponentNames()
+	data := []model.LogFeature{}
 
 	for _, component := range componentNames {
 
@@ -1151,3 +1164,231 @@
 	GenerateOutput(&result)
 	return nil
 }
+
+// This method enables log correlation for components.
+// For example, using below command, log correlation can be enabled for specific component
+// voltctl log correlation enable <componentName>
+// Omitting the component name will enable log correlation for all the components, as shown in below command.
+// voltctl log correlation enable
+func (options *EnableLogCorrelationOpts) Execute(args []string) error {
+	ProcessGlobalOptions()
+
+	log.SetAllLogLevel(log.FatalLevel)
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
+	defer cancel()
+
+	cm, cleanupFunc, err := constructConfigManager(ctx)
+	if err != nil {
+		return fmt.Errorf("Error while constructing ConfigManager instance : %s", err)
+	}
+	defer cleanupFunc()
+
+	var output []LogLevelOutput
+	var componentNames []string
+
+	if len(options.Args.Component) == 0 {
+		// Apply to all components if no specific component has been indicated
+		componentNames, err = cm.RetrieveComponentList(ctx, config.ConfigTypeLogFeatures)
+		if err != nil {
+			return fmt.Errorf("Unable to retrieve list of voltha components : %s ", err)
+		}
+	} else {
+		for _, name := range options.Args.Component {
+			componentNames = append(componentNames, string(name))
+		}
+	}
+
+	validComponents := getVolthaComponentNames()
+
+	for _, component := range componentNames {
+		config := cm.InitComponentConfig(component, config.ConfigTypeLogFeatures)
+		err := config.Save(ctx, logCorrelationStatusKey, "ENABLED")
+
+		if err != nil {
+			output = append(output, LogLevelOutput{ComponentName: component, Status: "Failure", Error: err.Error()})
+			continue
+		}
+
+		outmsg := ""
+		cvalid := false
+		for _, cname := range validComponents {
+			if component == cname {
+				cvalid = true
+				break
+			}
+		}
+		// For invalid component, add * against its name to indicate possible mis-configuration
+		if !cvalid {
+			component = "*" + component
+			outmsg = "Entered Component Name is not Currently active in Voltha"
+		}
+		output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
+	}
+
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("log-correlation-enable", "format", DEFAULT_LOG_FEATURE_RESULT_FORMAT)
+	}
+
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      output,
+	}
+	GenerateOutput(&result)
+	return nil
+}
+
+// This method disables log correlation for components.
+// For example, using below command, log correlation can be disabled for specific component
+// voltctl log correlation disable <componentName>
+// Omitting the component name will disable log correlation for all the components, as shown in below command.
+// voltctl log correlation disable
+func (options *DisableLogCorrelationOpts) Execute(args []string) error {
+	ProcessGlobalOptions()
+
+	log.SetAllLogLevel(log.FatalLevel)
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
+	defer cancel()
+
+	cm, cleanupFunc, err := constructConfigManager(ctx)
+	if err != nil {
+		return fmt.Errorf("Error while constructing ConfigManager instance : %s", err)
+	}
+	defer cleanupFunc()
+
+	var output []LogLevelOutput
+	var componentNames []string
+
+	if len(options.Args.Component) == 0 {
+		// Apply to all components if no specific component has been indicated
+		componentNames, err = cm.RetrieveComponentList(ctx, config.ConfigTypeLogFeatures)
+		if err != nil {
+			return fmt.Errorf("Unable to retrieve list of voltha components : %s ", err)
+		}
+	} else {
+		for _, name := range options.Args.Component {
+			componentNames = append(componentNames, string(name))
+		}
+	}
+
+	validComponents := getVolthaComponentNames()
+
+	for _, component := range componentNames {
+
+		config := cm.InitComponentConfig(component, config.ConfigTypeLogFeatures)
+		err := config.Save(ctx, logCorrelationStatusKey, "DISABLED")
+
+		if err != nil {
+			output = append(output, LogLevelOutput{ComponentName: component, Status: "Failure", Error: err.Error()})
+			continue
+		}
+		outmsg := ""
+		cvalid := false
+		for _, cname := range validComponents {
+			if component == cname {
+				cvalid = true
+				break
+			}
+		}
+		// For invalid component, add * against its name to indicate possible mis-configuration
+		if !cvalid {
+			component = "*" + component
+			outmsg = "Entered Component Name is not Currently active in Voltha"
+		}
+		output = append(output, LogLevelOutput{ComponentName: component, Status: "Success", Error: outmsg})
+	}
+
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("log-correlation-disable", "format", DEFAULT_LOG_FEATURE_RESULT_FORMAT)
+	}
+
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      output,
+	}
+	GenerateOutput(&result)
+	return nil
+}
+
+// This method lists current status of log correlation for components.
+// For example, using below command, log correlation can be queried for specific component
+// voltctl log correlation list <componentName>
+// Omitting the component name will list log correlation for all the components, as shown in below command.
+// voltctl log correlation list
+func (options *ListLogCorrelationOpts) Execute(args []string) error {
+	ProcessGlobalOptions()
+	log.SetAllLogLevel(log.FatalLevel)
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.KvStoreConfig.Timeout)
+	defer cancel()
+
+	cm, cleanupFunc, err := constructConfigManager(ctx)
+	if err != nil {
+		return fmt.Errorf("Error while constructing ConfigManager instance : %s", err)
+	}
+	defer cleanupFunc()
+
+	var componentNames []string
+	if len(options.Args.Component) == 0 {
+		// Apply to all components if no specific component has been indicated
+		componentNames, err = cm.RetrieveComponentList(ctx, config.ConfigTypeLogFeatures)
+		if err != nil {
+			return fmt.Errorf("Unable to retrieve list of voltha components : %s ", err)
+		}
+	} else {
+		for _, name := range options.Args.Component {
+			componentNames = append(componentNames, string(name))
+		}
+	}
+
+	validComponents := getVolthaComponentNames()
+	data := []model.LogFeature{}
+
+	for _, component := range componentNames {
+		config := cm.InitComponentConfig(component, config.ConfigTypeLogFeatures)
+		value, err := config.Retrieve(ctx, logCorrelationStatusKey)
+		if err != nil || value == "" {
+			// Ignore any error in retrieval; move to next component
+			continue
+		}
+		cvalid := false
+
+		for _, cname := range validComponents {
+			if component == cname {
+				cvalid = true
+				break
+			}
+		}
+		// For invalid component, add * against its name to indicate possible mis-configuration
+		if !cvalid {
+			component = "*" + component
+		}
+		logCorrelationStatus := model.LogFeature{}
+		logCorrelationStatus.PopulateFrom(component, value)
+		data = append(data, logCorrelationStatus)
+	}
+
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("log-correlation-list", "format", DEFAULT_LOG_FEATURE_STATUS_FORMAT)
+	}
+	orderBy := options.OrderBy
+	if orderBy == "" {
+		orderBy = GetCommandOptionWithDefault("log-correlation-list", "order", "ComponentName,Status")
+	}
+
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		Filter:    options.Filter,
+		OrderBy:   orderBy,
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      data,
+	}
+	GenerateOutput(&result)
+	return nil
+}
