diff --git a/jsonnet/kube-prometheus/kube-prometheus.libsonnet b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
index d5811aef43520c26b76fa09ee90f6dc0753bc88a..a089102758f5079f0d91a05d9345171985e0a6de 100644
--- a/jsonnet/kube-prometheus/kube-prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
@@ -1,16 +1,14 @@
-local kubeRbacProxyContainer = import './kube-rbac-proxy/containerMixin.libsonnet';
-
 local alertmanager = import './alertmanager/alertmanager.libsonnet';
 local blackboxExporter = import './blackbox-exporter/blackbox-exporter.libsonnet';
 local kubeStateMetrics = import './kube-state-metrics/kube-state-metrics.libsonnet';
 local nodeExporter = import './node-exporter/node-exporter.libsonnet';
 local prometheusAdapter = import './prometheus-adapter/prometheus-adapter.libsonnet';
+local prometheusOperator = import './prometheus-operator/prometheus-operator.libsonnet';
 local prometheus = import './prometheus/prometheus.libsonnet';
 
 local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
 
 (import 'github.com/brancz/kubernetes-grafana/grafana/grafana.libsonnet') +
-(import 'github.com/prometheus-operator/prometheus-operator/jsonnet/prometheus-operator/prometheus-operator.libsonnet') +
 {
   alertmanager: alertmanager({
     name: $._config.alertmanagerName,
@@ -47,6 +45,15 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     image: 'directxman12/k8s-prometheus-adapter:v0.8.2',
     prometheusURL: 'http://prometheus-' + $._config.prometheus.name + '.' + $._config.namespace + '.svc.cluster.local:9090/',
   }),
+  prometheusOperator: prometheusOperator({
+    namespace: $._config.namespace,
+    version: '0.45.0',
+    image: 'quay.io/prometheus-operator/prometheus-operator:v0.45.0',
+    configReloaderImage: 'quay.io/prometheus-operator/prometheus-config-reloader:v0.45.0',
+    commonLabels+: {
+      'app.kubernetes.io/part-of': 'kube-prometheus',
+    },
+  }),
   mixins+:: monitoringMixins({
     namespace: $._config.namespace,
     alertmanagerName: $._config.alertmanagerName,
@@ -76,62 +83,6 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
       },
     },
   },
-  prometheusOperator+::
-    {
-      service+: {
-        spec+: {
-          ports: [
-            {
-              name: 'https',
-              port: 8443,
-              targetPort: 'https',
-            },
-          ],
-        },
-      },
-      serviceMonitor+: {
-        spec+: {
-          endpoints: [
-            {
-              port: 'https',
-              scheme: 'https',
-              honorLabels: true,
-              bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
-              tlsConfig: {
-                insecureSkipVerify: true,
-              },
-            },
-          ],
-        },
-      },
-      clusterRole+: {
-        rules+: [
-          {
-            apiGroups: ['authentication.k8s.io'],
-            resources: ['tokenreviews'],
-            verbs: ['create'],
-          },
-          {
-            apiGroups: ['authorization.k8s.io'],
-            resources: ['subjectaccessreviews'],
-            verbs: ['create'],
-          },
-        ],
-      },
-    } +
-    (kubeRbacProxyContainer {
-       config+:: {
-         kubeRbacProxy: {
-           image: $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy,
-           name: 'kube-rbac-proxy',
-           securePortName: 'https',
-           securePort: 8443,
-           secureListenAddress: ':%d' % self.securePort,
-           upstream: 'http://127.0.0.1:8080/',
-           tlsCipherSuites: $._config.tlsCipherSuites,
-         },
-       },
-     }).deploymentMixin,
 
   grafana+:: {
     local dashboardDefinitions = super.dashboardDefinitions,
diff --git a/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet b/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..914695037624996f63c114556aca0708c8e1f95d
--- /dev/null
+++ b/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
@@ -0,0 +1,109 @@
+local krp = (import '../kube-rbac-proxy/container.libsonnet');
+local prometheusOperator = import 'github.com/prometheus-operator/prometheus-operator/jsonnet/prometheus-operator/prometheus-operator.libsonnet';
+
+local defaults = {
+  local defaults = self,
+  name: 'prometheus-operator',
+  namespace: error 'must provide namespace',
+  version: error 'must provide version',
+  image: error 'must provide image',
+  configReloaderImage: error 'must provide config reloader image',
+  resources: {
+    limits: { cpu: '200m', memory: '200Mi' },
+    requests: { cpu: '100m', memory: '100Mi' },
+  },
+  commonLabels:: {
+    'app.kubernetes.io/name': defaults.name,
+    'app.kubernetes.io/version': defaults.version,
+    'app.kubernetes.io/component': 'controller',
+    'app.kubernetes.io/part-of': 'kube-prometheus',
+  },
+  selectorLabels:: {
+    [labelName]: defaults.commonLabels[labelName]
+    for labelName in std.objectFields(defaults.commonLabels)
+    if !std.setMember(labelName, ['app.kubernetes.io/version'])
+  },
+};
+
+function(params) {
+  local po = self,
+  config:: defaults + params,
+  // Safety check
+  assert std.isObject(po.config.resources),
+
+  //TODO(paulfantom): it would be better to include it on the same level as self.
+  local polib = prometheusOperator(po.config),
+
+  '0alertmanagerConfigCustomResourceDefinition': polib['0alertmanagerConfigCustomResourceDefinition'],
+  '0alertmanagerCustomResourceDefinition': polib['0alertmanagerCustomResourceDefinition'],
+  '0podmonitorCustomResourceDefinition': polib['0podmonitorCustomResourceDefinition'],
+  '0probeCustomResourceDefinition': polib['0probeCustomResourceDefinition'],
+  '0prometheusCustomResourceDefinition': polib['0prometheusCustomResourceDefinition'],
+  '0prometheusruleCustomResourceDefinition': polib['0prometheusruleCustomResourceDefinition'],
+  '0servicemonitorCustomResourceDefinition': polib['0servicemonitorCustomResourceDefinition'],
+  '0thanosrulerCustomResourceDefinition': polib['0thanosrulerCustomResourceDefinition'],
+
+  serviceAccount: polib.serviceAccount,
+  service: polib.service {
+    spec+: {
+      ports: [
+        {
+          name: 'https',
+          port: 8443,
+          targetPort: 'https',
+        },
+      ],
+    },
+  },
+
+  serviceMonitor: polib.serviceMonitor {
+    spec+: {
+      endpoints: [
+        {
+          port: 'https',
+          scheme: 'https',
+          honorLabels: true,
+          bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
+          tlsConfig: {
+            insecureSkipVerify: true,
+          },
+        },
+      ],
+    },
+  },
+
+  clusterRoleBinding: polib.clusterRoleBinding,
+  clusterRole: polib.clusterRole {
+    rules+: [
+      {
+        apiGroups: ['authentication.k8s.io'],
+        resources: ['tokenreviews'],
+        verbs: ['create'],
+      },
+      {
+        apiGroups: ['authorization.k8s.io'],
+        resources: ['subjectaccessreviews'],
+        verbs: ['create'],
+      },
+    ],
+  },
+
+  local kubeRbacProxy = krp({
+    name: 'kube-rbac-proxy',
+    upstream: 'http://127.0.0.1:8080/',
+    secureListenAddress: ':8443',
+    ports: [
+      { name: 'https', containerPort: 8443 },
+    ],
+  }),
+
+  deployment: polib.deployment {
+    spec+: {
+      template+: {
+        spec+: {
+          containers+: [kubeRbacProxy],
+        },
+      },
+    },
+  },
+}