diff --git a/docs/cri-o.md b/docs/cri-o.md
index ab7bdc1cf79b5678c308f781e815c747eb25599e..5644d2e037e2dd61aa687e9238cbb18bb895a682 100644
--- a/docs/cri-o.md
+++ b/docs/cri-o.md
@@ -60,3 +60,24 @@ crio_pids_limit: 4096
 
 [CRI-O]: https://cri-o.io/
 [cri-o#1921]: https://github.com/cri-o/cri-o/issues/1921
+
+## Note about user namespaces
+
+CRI-O has support for user namespaces. This feature is optional and can be enabled by setting the following two variables.
+
+```yaml
+crio_runtimes:
+  - name: runc
+    path: /usr/bin/runc
+    type: oci
+    root: /run/runc
+    allowed_annotations:
+    - "io.kubernetes.cri-o.userns-mode"
+
+crio_remap_enable: true
+```
+
+The `allowed_annotations` configures `crio.conf` accordingly.
+
+The `crio_remap_enable` configures the `/etc/subuid` and `/etc/subgid` files to add an entry for the **containers** user.
+By default, 16M uids and gids are reserved for user namespaces (256 pods * 65536 uids/gids) at the end of the uid/gid space.
diff --git a/roles/container-engine/cri-o/defaults/main.yml b/roles/container-engine/cri-o/defaults/main.yml
index f49e330732bec46db1e3b3053eb3fdcc45806d29..7e7a63660607a4311ecb418aea55169219d16937 100644
--- a/roles/container-engine/cri-o/defaults/main.yml
+++ b/roles/container-engine/cri-o/defaults/main.yml
@@ -97,3 +97,12 @@ skopeo_packages:
 # Configure the cri-o pids limit, increase this for heavily multi-threaded workloads
 # see https://github.com/cri-o/cri-o/issues/1921
 crio_pids_limit: 1024
+
+# Reserve 16M uids and gids for user namespaces (256 pods * 65536 uids/gids)
+# at the end of the uid/gid space
+crio_remap_enable: false
+crio_remap_user: containers
+crio_subuid_start: 2130706432
+crio_subuid_length: 16777216
+crio_subgid_start: 2130706432
+crio_subgid_length: 16777216
diff --git a/roles/container-engine/cri-o/tasks/main.yaml b/roles/container-engine/cri-o/tasks/main.yaml
index 45e60ef747f3edf905985191142feb3544eaf553..3341594e282d2bedb7dabefe07d9fec88f0aab18 100644
--- a/roles/container-engine/cri-o/tasks/main.yaml
+++ b/roles/container-engine/cri-o/tasks/main.yaml
@@ -182,6 +182,20 @@
   notify: restart crio
   when: http_proxy is defined or https_proxy is defined
 
+- name: Configure the uid/gid space for user namespaces
+  lineinfile:
+    path: '{{ item.path }}'
+    line: '{{ item.entry }}'
+    regex: '^\s*{{ crio_remap_user }}:'
+    state: '{{ "present" if crio_remap_enable | bool else "absent" }}'
+  loop:
+    - path: /etc/subuid
+      entry: '{{ crio_remap_user }}:{{ crio_subuid_start }}:{{ crio_subuid_length }}'
+    - path: /etc/subgid
+      entry: '{{ crio_remap_user }}:{{ crio_subgid_start }}:{{ crio_subgid_length }}'
+  loop_control:
+    label: '{{ item.path }}'
+
 - name: Ensure crio service is started and enabled
   service:
     name: crio
diff --git a/roles/container-engine/cri-o/templates/crio.conf.j2 b/roles/container-engine/cri-o/templates/crio.conf.j2
index b6f5357dd1dbc33e4973933a77bb91fab305998b..8fbd23a1d40f05296a5c302a057e0564d298ae25 100644
--- a/roles/container-engine/cri-o/templates/crio.conf.j2
+++ b/roles/container-engine/cri-o/templates/crio.conf.j2
@@ -294,6 +294,7 @@ runtime_path = "{{ runtime.path }}"
 runtime_type = "{{ runtime.type }}"
 runtime_root = "{{ runtime.root }}"
 privileged_without_host_devices = {{ runtime.privileged_without_host_devices|default(false)|lower }}
+allowed_annotations = {{ runtime.allowed_annotations|default([])|to_json }}
 {% endfor %}
 
 # Kata Containers with the Firecracker VMM