diff --git a/deploy/chart/.helmignore b/deploy/chart/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..50af0317254197a5a019f4ac2f8ecc223f93f5a7
--- /dev/null
+++ b/deploy/chart/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/deploy/chart/Chart.yaml b/deploy/chart/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2354c0f13276499eadaec43789d814bef02ecc53
--- /dev/null
+++ b/deploy/chart/Chart.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+appVersion: "0.0.9"
+description: Use HostPath for persistent local storage with Kubernetes
+name: local-path-provisioner
+version: 0.0.9
+keywords:
+  - storage
+  - hostpath
+kubeVersion: ">=1.12.0"
+home: https://github.com/rancher/local-path-provisioner
+sources:
+  - https://github.com/rancher/local-path-provisioner.git
diff --git a/deploy/chart/README.md b/deploy/chart/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d40ea40907c8d485ee713d1f9ca4a7c010f3b3c0
--- /dev/null
+++ b/deploy/chart/README.md
@@ -0,0 +1,111 @@
+# Local Path Provisioner
+
+[Local Path Provisioner](https://github.com/rancher/local-path-provisioner) provides a way for the Kubernetes users to
+utilize the local storage in each node. Based on the user configuration, the Local Path Provisioner will create
+`hostPath` based persistent volume on the node automatically. It utilizes the features introduced by Kubernetes [Local
+Persistent Volume feature](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/), but make it a simpler
+solution than the built-in `local` volume feature in Kubernetes.
+
+## TL;DR;
+
+```console
+$ git clone https://github.com/rancher/local-path-provisioner.git
+$ cd local-path-provisioner
+$ helm install --name local-path-storage --namespace local-path-storage ./deploy/chart/
+```
+
+## Introduction
+
+This chart bootstraps a [Local Path Provisioner](https://github.com/rancher/local-path-provisioner) deployment on a
+[Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
+
+## Prerequisites
+
+- Kubernetes 1.12+ with Beta APIs enabled
+
+## Installing the Chart
+
+To install the chart with the release name `local-path-storage`:
+
+```console
+$ git clone https://github.com/rancher/local-path-provisioner.git
+$ cd local-path-provisioner
+$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage
+```
+
+The command deploys Local Path Provisioner on the Kubernetes cluster in the default configuration. The
+[configuration](#configuration) section lists the parameters that can be configured during installation.
+
+> **Tip**: List all releases using `helm list`
+
+## Uninstalling the Chart
+
+To uninstall/delete the `local-path-storage` deployment:
+
+```console
+$ helm delete --purge local-path-storage
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Configuration
+
+The following table lists the configurable parameters of the Local Path Provisioner for Kubernetes chart and their
+default values.
+
+| Parameter                           | Description                                                                     | Default                                                                             |
+| ----------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
+| `image.repository`                  | Local Path Provisioner image name                                               | `rancher/local-path-provisioner`                                                    |
+| `image.tag`                         | Local Path Provisioner image tag                                                | `v0.0.9`                                                                            |
+| `image.pullPolicy`                  | Image pull policy                                                               | `IfNotPresent`                                                                      |
+| `storageClass.create`               | If true, create a `StorageClass`                                                | `true`                                                                              |
+| `storageClass.provisionerName`      | The provisioner name for the storage class                                      | `nil`                                                                               |
+| `storageClass.defaultClass`         | If true, set the created `StorageClass` as the cluster's default `StorageClass` | `false`                                                                             |
+| `storageClass.name`                 | The name to assign the created StorageClass                                     | local-path                                                                          |
+| `storageClass.reclaimPolicy`        | ReclaimPolicy field of the class                                                | Delete                                                                              |
+| `nodePathMap`                       | Configuration of where to store the data on each node                           | `[{node: DEFAULT_PATH_FOR_NON_LISTED_NODES, paths: [/opt/local-path-provisioner]}]` |
+| `resources`                         | Local Path Provisioner resource requests & limits                               | `{}`                                                                                |
+| `rbac.create`                       | If true, create & use RBAC resources                                            | `true`                                                                              |
+| `serviceAccount.create`             | If true, create the Local Path Provisioner service account                      | `true`                                                                              |
+| `serviceAccount.name`               | Name of the Local Path Provisioner service account to use or create             | `nil`                                                                               |
+| `nodeSelector`                      | Node labels for Local Path Provisioner pod assignment                           | `{}`                                                                                |
+| `tolerations`                       | Node taints to tolerate                                                         | `[]`                                                                                |
+| `affinity`                          | Pod affinity                                                                    | `{}`                                                                                |
+
+Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
+
+```console
+$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage --set storageClass.provisionerName=rancher.io/local-path
+```
+
+Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the
+chart. For example,
+
+```console
+$ helm install --name local-path-storage --namespace local-path-storage ./deploy/chart/ -f values.yaml
+```
+
+> **Tip**: You can use the default [values.yaml](values.yaml)
+
+## RBAC
+
+By default the chart will install the recommended RBAC roles and rolebindings.
+
+You need to have the flag `--authorization-mode=RBAC` on the api server. See the following document for how to enable
+[RBAC](https://kubernetes.io/docs/admin/authorization/rbac/).
+
+To determine if your cluster supports RBAC, run the following command:
+
+```console
+$ kubectl api-versions | grep rbac
+```
+
+If the output contains "beta", you may install the chart with RBAC enabled (see below).
+
+### Enable RBAC role/rolebinding creation
+
+To enable the creation of RBAC resources (On clusters with RBAC). Do the following:
+
+```console
+$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage --set rbac.create=true
+```
diff --git a/deploy/chart/templates/NOTES.txt b/deploy/chart/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..25370acc7d6bf9361c8bd7776a666036b425285b
--- /dev/null
+++ b/deploy/chart/templates/NOTES.txt
@@ -0,0 +1,13 @@
+You can create a hostpath-backed persistent volume with a persistent volume claim like this:
+
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: local-path-pvc
+spec:
+  accessModes:
+    - ReadWriteOnce
+  storageClassName: {{ .Values.storageClass.name }}
+  resources:
+    requests:
+      storage: 2Gi
diff --git a/deploy/chart/templates/_helpers.tpl b/deploy/chart/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..c581eec4c8b4c0085773769d17f56f0b9500af1f
--- /dev/null
+++ b/deploy/chart/templates/_helpers.tpl
@@ -0,0 +1,67 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "local-path-provisioner.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "local-path-provisioner.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "local-path-provisioner.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "local-path-provisioner.labels" -}}
+app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
+helm.sh/chart: {{ include "local-path-provisioner.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use.
+*/}}
+{{- define "local-path-provisioner.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "local-path-provisioner.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create the name of the provisioner to use.
+*/}}
+{{- define "local-path-provisioner.provisionerName" -}}
+{{- if .Values.storageClass.provisionerName -}}
+{{- printf .Values.storageClass.provisionerName -}}
+{{- else -}}
+cluster.local/{{ template "local-path-provisioner.fullname" . -}}
+{{- end -}}
+{{- end -}}
diff --git a/deploy/chart/templates/clusterrole.yaml b/deploy/chart/templates/clusterrole.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..12354955cebf55369ce6251d59f55e3a378ddb23
--- /dev/null
+++ b/deploy/chart/templates/clusterrole.yaml
@@ -0,0 +1,21 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  name: {{ include "local-path-provisioner.fullname" . }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+rules:
+- apiGroups: [""]
+  resources: ["nodes", "persistentvolumeclaims"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: [""]
+  resources: ["endpoints", "persistentvolumes", "pods"]
+  verbs: ["*"]
+- apiGroups: [""]
+  resources: ["events"]
+  verbs: ["create", "patch"]
+- apiGroups: ["storage.k8s.io"]
+  resources: ["storageclasses"]
+  verbs: ["get", "list", "watch"]
+{{- end -}}
diff --git a/deploy/chart/templates/clusterrolebinding.yaml b/deploy/chart/templates/clusterrolebinding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..46e7d0f681cf7c9b7901cc1c8042fbf791e9fe27
--- /dev/null
+++ b/deploy/chart/templates/clusterrolebinding.yaml
@@ -0,0 +1,16 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "local-path-provisioner.fullname" . }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ template "local-path-provisioner.fullname" . }}
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "local-path-provisioner.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace }}
+{{- end -}}
diff --git a/deploy/chart/templates/configmap.yaml b/deploy/chart/templates/configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0b4f6078b7723477ac4c577dd83f35f9c0e1ec4d
--- /dev/null
+++ b/deploy/chart/templates/configmap.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "local-path-provisioner.fullname" . }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+data:
+apiVersion: v1
+data:
+  config.json: |-
+    {
+      "nodePathMap": {{ .Values.nodePathMap | toPrettyJson | nindent 8 }}
+    }
diff --git a/deploy/chart/templates/deployment.yaml b/deploy/chart/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eef9e07884ac75ffd6ec865ba4baa5ca0898181b
--- /dev/null
+++ b/deploy/chart/templates/deployment.yaml
@@ -0,0 +1,59 @@
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+  name: {{ include "local-path-provisioner.fullname" . }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "local-path-provisioner.serviceAccountName" . }}
+      containers:
+        - name: {{ .Chart.Name }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          command:
+            - local-path-provisioner
+            - --debug
+            - start
+            - --config
+            - /etc/config/config.json
+            - --provisioner-name
+            - {{ template "local-path-provisioner.provisionerName" . }}
+          volumeMounts:
+            - name: config-volume
+              mountPath: /etc/config/
+          env:
+            - name: POD_NAMESPACE
+              value: {{ .Release.Namespace }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      volumes:
+        - name: config-volume
+          configMap:
+            name: {{ include "local-path-provisioner.fullname" . }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/deploy/chart/templates/serviceaccount.yaml b/deploy/chart/templates/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..19faf0d59847707f604ab0c97aef84cdff539e96
--- /dev/null
+++ b/deploy/chart/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "local-path-provisioner.fullname" . }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+{{- end }}
diff --git a/deploy/chart/templates/storageclass.yaml b/deploy/chart/templates/storageclass.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c451b82739869cee199edf0bdc0f24e264a2b505
--- /dev/null
+++ b/deploy/chart/templates/storageclass.yaml
@@ -0,0 +1,15 @@
+{{ if .Values.storageClass.create -}}
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: {{ .Values.storageClass.name }}
+  labels:
+{{ include "local-path-provisioner.labels" . | indent 4 }}
+{{- if .Values.storageClass.defaultClass }}
+  annotations:
+    storageclass.kubernetes.io/is-default-class: "true"
+{{- end }}
+provisioner: {{ template "local-path-provisioner.provisionerName" . }}
+volumeBindingMode: WaitForFirstConsumer
+reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }}
+{{- end }}
diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b9a87885e7a1b1591ef0701dae54b6158ac95877
--- /dev/null
+++ b/deploy/chart/values.yaml
@@ -0,0 +1,76 @@
+# Default values for local-path-provisioner.
+
+replicaCount: 1
+
+image:
+  repository: rancher/local-path-provisioner
+  tag: v0.0.9
+  pullPolicy: IfNotPresent
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+## For creating the StorageClass automatically:
+storageClass:
+  create: true
+
+  ## Set a provisioner name. If unset, a name will be generated.
+  # provisionerName: rancher.io/local-path
+
+  ## Set StorageClass as the default StorageClass
+  ## Ignored if storageClass.create is false
+  defaultClass: false
+
+  ## Set a StorageClass name
+  ## Ignored if storageClass.create is false
+  name: local-path
+
+  ## ReclaimPolicy field of the class, which can be either Delete or Retain
+  reclaimPolicy: Delete
+
+# nodePathMap is the place user can customize where to store the data on each node.
+# 1. If one node is not listed on the nodePathMap, and Kubernetes wants to create volume on it, the paths specified in
+#    DEFAULT_PATH_FOR_NON_LISTED_NODES will be used for provisioning.
+# 2. If one node is listed on the nodePathMap, the specified paths will be used for provisioning.
+#     1. If one node is listed but with paths set to [], the provisioner will refuse to provision on this node.
+#     2. If more than one path was specified, the path would be chosen randomly when provisioning.
+#
+# The configuration must obey following rules:
+# 1. A path must start with /, a.k.a an absolute path.
+# 2. Root directory (/) is prohibited.
+# 3. No duplicate paths allowed for one node.
+# 4. No duplicate node allowed.
+nodePathMap:
+  - node: DEFAULT_PATH_FOR_NON_LISTED_NODES
+    paths:
+      - /opt/local-path-provisioner
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+rbac:
+  # Specifies whether RBAC resources should be created
+  create: true
+
+serviceAccount:
+  # Specifies whether a ServiceAccount should be created
+  create: true
+  # The name of the ServiceAccount to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name:
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}