diff --git a/api/v1alpha1/clusterdeployment_types.go b/api/v1alpha1/clusterdeployment_types.go
index dc56d98be..f963f5784 100644
--- a/api/v1alpha1/clusterdeployment_types.go
+++ b/api/v1alpha1/clusterdeployment_types.go
@@ -15,6 +15,9 @@
 package v1alpha1
 
 import (
+	"encoding/json"
+	"fmt"
+
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -124,11 +127,39 @@ type ClusterDeployment struct {
 	Status ClusterDeploymentStatus `json:"status,omitempty"`
 }
 
-func (in *ClusterDeployment) HelmValues() (values map[string]any, err error) {
+func (in *ClusterDeployment) HelmValues() (map[string]any, error) {
+	var values map[string]any
+
 	if in.Spec.Config != nil {
-		err = yaml.Unmarshal(in.Spec.Config.Raw, &values)
+		if err := yaml.Unmarshal(in.Spec.Config.Raw, &values); err != nil {
+			return nil, fmt.Errorf("error unmarshalling helm values for clusterTemplate %s: %w", in.Spec.Template, err)
+		}
 	}
-	return values, err
+
+	return values, nil
+}
+
+func (in *ClusterDeployment) SetHelmValues(values map[string]any) error {
+	b, err := json.Marshal(values)
+	if err != nil {
+		return fmt.Errorf("error marshalling helm values for clusterTemplate %s: %w", in.Spec.Template, err)
+	}
+
+	in.Spec.Config = &apiextensionsv1.JSON{Raw: b}
+	return nil
+}
+
+func (in *ClusterDeployment) AddHelmValues(fn func(map[string]any) error) error {
+	values, err := in.HelmValues()
+	if err != nil {
+		return err
+	}
+
+	if err := fn(values); err != nil {
+		return err
+	}
+
+	return in.SetHelmValues(values)
 }
 
 func (in *ClusterDeployment) GetConditions() *[]metav1.Condition {
diff --git a/internal/controller/clusterdeployment_controller.go b/internal/controller/clusterdeployment_controller.go
index c6f02d4f8..991270480 100644
--- a/internal/controller/clusterdeployment_controller.go
+++ b/internal/controller/clusterdeployment_controller.go
@@ -16,7 +16,6 @@ package controller
 
 import (
 	"context"
-	"encoding/json"
 	"errors"
 	"fmt"
 	"slices"
@@ -31,7 +30,6 @@ import (
 	"helm.sh/helm/v3/pkg/action"
 	"helm.sh/helm/v3/pkg/chart"
 	corev1 "k8s.io/api/core/v1"
-	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -297,13 +295,21 @@ func (r *ClusterDeploymentReconciler) updateCluster(ctx context.Context, mc *hmc
 		return ctrl.Result{}, nil
 	}
 
-	helmValues, err := setIdentityHelmValues(mc.Spec.Config, cred.Spec.IdentityRef)
-	if err != nil {
-		return ctrl.Result{}, fmt.Errorf("error setting identity values: %w", err)
+	if err := mc.AddHelmValues(func(values map[string]any) error {
+		values["clusterIdentity"] = cred.Spec.IdentityRef
+
+		if _, ok := values["clusterLabels"]; !ok {
+			// Use the ManagedCluster's own labels if not defined.
+			values["clusterLabels"] = mc.GetObjectMeta().GetLabels()
+		}
+
+		return nil
+	}); err != nil {
+		return ctrl.Result{}, err
 	}
 
 	hrReconcileOpts := helm.ReconcileHelmReleaseOpts{
-		Values: helmValues,
+		Values: mc.Spec.Config,
 		OwnerReference: &metav1.OwnerReference{
 			APIVersion: hmc.GroupVersion.String(),
 			Kind:       hmc.ClusterDeploymentKind,
@@ -798,22 +804,6 @@ func (r *ClusterDeploymentReconciler) reconcileCredentialPropagation(ctx context
 	return nil
 }
 
-func setIdentityHelmValues(values *apiextensionsv1.JSON, idRef *corev1.ObjectReference) (*apiextensionsv1.JSON, error) {
-	var valuesJSON map[string]any
-	err := json.Unmarshal(values.Raw, &valuesJSON)
-	if err != nil {
-		return nil, fmt.Errorf("error unmarshalling values: %w", err)
-	}
-
-	valuesJSON["clusterIdentity"] = idRef
-	valuesRaw, err := json.Marshal(valuesJSON)
-	if err != nil {
-		return nil, fmt.Errorf("error marshalling values: %w", err)
-	}
-
-	return &apiextensionsv1.JSON{Raw: valuesRaw}, nil
-}
-
 func (r *ClusterDeploymentReconciler) setAvailableUpgrades(ctx context.Context, clusterDeployment *hmc.ClusterDeployment, template *hmc.ClusterTemplate) error {
 	if template == nil {
 		return nil
diff --git a/templates/cluster/aws-eks/templates/cluster.yaml b/templates/cluster/aws-eks/templates/cluster.yaml
index dca896de1..1058a3983 100644
--- a/templates/cluster/aws-eks/templates/cluster.yaml
+++ b/templates/cluster/aws-eks/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/aws-eks/values.yaml b/templates/cluster/aws-eks/values.yaml
index 188b7818b..35e244198 100644
--- a/templates/cluster/aws-eks/values.yaml
+++ b/templates/cluster/aws-eks/values.yaml
@@ -9,6 +9,8 @@ clusterNetwork:
     cidrBlocks:
       - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # EKS cluster parameters
 region: ""
 sshKeyName: ""
diff --git a/templates/cluster/aws-hosted-cp/templates/cluster.yaml b/templates/cluster/aws-hosted-cp/templates/cluster.yaml
index eaef59c58..b16fa98cd 100644
--- a/templates/cluster/aws-hosted-cp/templates/cluster.yaml
+++ b/templates/cluster/aws-hosted-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/aws-hosted-cp/values.yaml b/templates/cluster/aws-hosted-cp/values.yaml
index c018fe1fd..7dd0ec931 100644
--- a/templates/cluster/aws-hosted-cp/values.yaml
+++ b/templates/cluster/aws-hosted-cp/values.yaml
@@ -9,6 +9,8 @@ clusterNetwork:
     cidrBlocks:
       - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # AWS cluster parameters
 vpcID: ""
 region: ""
diff --git a/templates/cluster/aws-standalone-cp/templates/cluster.yaml b/templates/cluster/aws-standalone-cp/templates/cluster.yaml
index cb3425af5..652821268 100644
--- a/templates/cluster/aws-standalone-cp/templates/cluster.yaml
+++ b/templates/cluster/aws-standalone-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/aws-standalone-cp/values.yaml b/templates/cluster/aws-standalone-cp/values.yaml
index 6f0a019db..94ceaea0a 100644
--- a/templates/cluster/aws-standalone-cp/values.yaml
+++ b/templates/cluster/aws-standalone-cp/values.yaml
@@ -10,6 +10,8 @@ clusterNetwork:
     cidrBlocks:
       - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # AWS cluster parameters
 region: ""
 sshKeyName: ""
diff --git a/templates/cluster/azure-hosted-cp/templates/cluster.yaml b/templates/cluster/azure-hosted-cp/templates/cluster.yaml
index 74bd07a54..9903c5dcf 100644
--- a/templates/cluster/azure-hosted-cp/templates/cluster.yaml
+++ b/templates/cluster/azure-hosted-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/azure-hosted-cp/values.yaml b/templates/cluster/azure-hosted-cp/values.yaml
index b4e1b81e6..61decb161 100644
--- a/templates/cluster/azure-hosted-cp/values.yaml
+++ b/templates/cluster/azure-hosted-cp/values.yaml
@@ -10,6 +10,8 @@ clusterNetwork:
     cidrBlocks:
     - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # Azure cluster parameters
 location: ""
 subscriptionID: ""
diff --git a/templates/cluster/azure-standalone-cp/templates/cluster.yaml b/templates/cluster/azure-standalone-cp/templates/cluster.yaml
index 2ce7581f7..eb5582eaa 100644
--- a/templates/cluster/azure-standalone-cp/templates/cluster.yaml
+++ b/templates/cluster/azure-standalone-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/azure-standalone-cp/values.yaml b/templates/cluster/azure-standalone-cp/values.yaml
index bd7504aad..f156d1c99 100644
--- a/templates/cluster/azure-standalone-cp/values.yaml
+++ b/templates/cluster/azure-standalone-cp/values.yaml
@@ -10,6 +10,8 @@ clusterNetwork:
     cidrBlocks:
     - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # Azure cluster parameters
 location: ""
 subscriptionID: ""
diff --git a/templates/cluster/vsphere-hosted-cp/templates/cluster.yaml b/templates/cluster/vsphere-hosted-cp/templates/cluster.yaml
index 87c042604..effe65665 100644
--- a/templates/cluster/vsphere-hosted-cp/templates/cluster.yaml
+++ b/templates/cluster/vsphere-hosted-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/vsphere-hosted-cp/values.yaml b/templates/cluster/vsphere-hosted-cp/values.yaml
index 187774dc8..ffc4d136e 100644
--- a/templates/cluster/vsphere-hosted-cp/values.yaml
+++ b/templates/cluster/vsphere-hosted-cp/values.yaml
@@ -10,6 +10,8 @@ clusterNetwork:
     cidrBlocks:
     - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # vSphere cluster parameters
 clusterIdentity:
   name: ""
diff --git a/templates/cluster/vsphere-standalone-cp/templates/cluster.yaml b/templates/cluster/vsphere-standalone-cp/templates/cluster.yaml
index c2437c246..b2585844c 100644
--- a/templates/cluster/vsphere-standalone-cp/templates/cluster.yaml
+++ b/templates/cluster/vsphere-standalone-cp/templates/cluster.yaml
@@ -2,6 +2,9 @@ apiVersion: cluster.x-k8s.io/v1beta1
 kind: Cluster
 metadata:
   name: {{ include "cluster.name" . }}
+  {{- if .Values.clusterLabels }}
+  labels: {{- toYaml .Values.clusterLabels | nindent 4}}
+  {{- end }}
 spec:
   {{- with .Values.clusterNetwork }}
   clusterNetwork:
diff --git a/templates/cluster/vsphere-standalone-cp/values.yaml b/templates/cluster/vsphere-standalone-cp/values.yaml
index eb64d7080..9da31851c 100644
--- a/templates/cluster/vsphere-standalone-cp/values.yaml
+++ b/templates/cluster/vsphere-standalone-cp/values.yaml
@@ -10,6 +10,8 @@ clusterNetwork:
     cidrBlocks:
     - "10.96.0.0/12"
 
+clusterLabels: {}
+
 # vSphere cluster parameters
 clusterIdentity:
   name: ""