diff --git a/README.md b/README.md
index 8eae7934b58214947aec87032090fcc7678b13a2..28a19a53c6e61a19d9227dd7f0a294a1c0bff7c1 100644
--- a/README.md
+++ b/README.md
@@ -118,7 +118,7 @@ Note: Upstart/SysV init based OS types are not supported.
   - [cri-o](http://cri-o.io/) v1.14.0 (experimental: see [CRI-O Note](docs/cri-o.md). Only on centos based OS)
 - Network Plugin
   - [cni-plugins](https://github.com/containernetworking/plugins) v0.8.1
-  - [calico](https://github.com/projectcalico/calico) v3.7.3
+  - [calico](https://github.com/projectcalico/calico) v3.11.1
   - [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
   - [cilium](https://github.com/cilium/cilium) v1.5.5
   - [contiv](https://github.com/contiv/install) v1.2.1
diff --git a/inventory/sample/group_vars/k8s-cluster/k8s-net-calico.yml b/inventory/sample/group_vars/k8s-cluster/k8s-net-calico.yml
index 3935681c24166b5f11e55227362ec3df1f3548a8..6d5987dc003777c9928703945f97fa8971c95a50 100644
--- a/inventory/sample/group_vars/k8s-cluster/k8s-net-calico.yml
+++ b/inventory/sample/group_vars/k8s-cluster/k8s-net-calico.yml
@@ -31,6 +31,9 @@
 # Choose data store type for calico: "etcd" or "kdd" (kubernetes datastore)
 # calico_datastore: "etcd"
 
+# Choose Calico iptables backend: "Iptables" or "NFT"
+# calico_iptables_backend: "Iptables"
+
 # Use typha (only with kdd)
 # typha_enabled: false
 
diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml
index 12d0276cd72c8cf26be904a18683aa54ccb84740..4df3444eff4c6f36f5b7f399dbf78bb3305eb02e 100644
--- a/roles/download/defaults/main.yml
+++ b/roles/download/defaults/main.yml
@@ -65,12 +65,12 @@ quay_image_repo: "quay.io"
 
 # TODO(mattymo): Move calico versions to roles/network_plugins/calico/defaults
 # after migration to container download
-calico_version: "v3.7.3"
-calico_ctl_version: "v3.7.3"
-calico_cni_version: "v3.7.3"
-calico_policy_version: "v3.7.3"
-calico_rr_version: "v0.6.1"
-calico_typha_version: "v3.7.3"
+calico_version: "v3.11.1"
+calico_ctl_version: "v3.11.1"
+calico_cni_version: "v3.11.1"
+calico_policy_version: "v3.11.1"
+calico_rr_version: "v0.6.3"
+calico_typha_version: "v3.11.1"
 typha_enabled: false
 
 flannel_version: "v0.11.0"
@@ -254,20 +254,23 @@ cni_binary_checksums:
   amd64: 29a092bef9cb6f26c8d5340f3d56567b62c7ebdb1321245d94b1842c80ba20ba
 calicoctl_binary_checksums:
   arm:
+    v3.11.1: 0
+    v3.7.3: 0
     v3.6.1: 0
     v3.5.4: 0
     v3.4.4: 0
-    v3.7.3: 0
   amd64:
+    v3.11.1: 045fdbfdb30789194c499ba17c8eac6d1704fe20d05e3c10027eb570767386db
+    v3.7.3: 932f68e893e80e95e10f064f1e7745e438d456f41a6ff12d11bb16ca0cab735c
     v3.6.1: 3b01336de37550e020343d62a38c96c4605d33a3ed7ddba2fe38bc172a5b42b5
     v3.5.4: 197194b838cc2a9a7455c2ebd5505a5e24f8f3d994eb75c17f5dd568944100b8
     v3.4.4: 93bd084e053cf1bf3b7fef369677bd6767c30fe7135e2c7e044e31693422ef61
-    v3.7.3: 932f68e893e80e95e10f064f1e7745e438d456f41a6ff12d11bb16ca0cab735c
   arm64:
+    v3.11.1: 770e0fce9acf1927726d64a885f8350d44a3fcbf248017d0aceec58bd41fa1b8
+    v3.7.3: 7cfaab25c287f7ef93b2682d060b55bf39f76b668540de50376b5ed174209832
     v3.6.1: 60fbaeb257061647bdf12b5ede7a0d4298a5ee216f6472e5a92bb14ef5c2a5d3
     v3.5.4: a4481178665658658a73e4ceca9a1dff5cccded4179615c91d1c3e49fd96f237
     v3.4.4: ff35d9e8b5c00e9fe47d05e8f5123ec98fd641370f8cd93f4fbb3d913da77ab6
-    v3.7.3: 7cfaab25c287f7ef93b2682d060b55bf39f76b668540de50376b5ed174209832
 
 etcd_binary_checksum: "{{ etcd_binary_checksums[image_arch] }}"
 cni_binary_checksum: "{{ cni_binary_checksums[image_arch] }}"
diff --git a/roles/network_plugin/calico/defaults/main.yml b/roles/network_plugin/calico/defaults/main.yml
index 61462ba943495a6a2a8935f4df7722f295df874d..277fa36b81bcf9fb80732db083e52f757c724b36 100644
--- a/roles/network_plugin/calico/defaults/main.yml
+++ b/roles/network_plugin/calico/defaults/main.yml
@@ -51,6 +51,9 @@ calico_node_ignorelooserpf: false
 # Define address on which Felix will respond to health requests
 calico_healthhost: "localhost"
 
+# Choose Calico iptables backend: "Iptables" or "NFT" (FELIX_IPTABLESBACKEND)
+calico_iptables_backend: "Iptables"
+
 # If you want to use non default IP_AUTODETECTION_METHOD for calico node set this option to one of:
 # * can-reach=DESTINATION
 # * interface=INTERFACE-REGEX
diff --git a/roles/network_plugin/calico/templates/calico-cr.yml.j2 b/roles/network_plugin/calico/templates/calico-cr.yml.j2
index cfffce3d3274e92e7d6a9bf212e24d45cdd262be..d818f3d9d9913e66f390d552bd51c7b638a60708 100644
--- a/roles/network_plugin/calico/templates/calico-cr.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-cr.yml.j2
@@ -1,6 +1,6 @@
 ---
 kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: calico-node
   namespace: kube-system
@@ -82,6 +82,9 @@ rules:
 {% endif %}
       - clusterinformations
       - hostendpoints
+{% if calico_version is version('v3.9.0', '>=') %}
+      - blockaffinities
+{% endif %}
     verbs:
       - get
       - list
diff --git a/roles/network_plugin/calico/templates/calico-crb.yml.j2 b/roles/network_plugin/calico/templates/calico-crb.yml.j2
index 1b4e8fe00972f721daf44cf4c699ae373095ec00..f747bfd18171a0bd9d89ee78e87c5c92b0b050e9 100644
--- a/roles/network_plugin/calico/templates/calico-crb.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-crb.yml.j2
@@ -1,5 +1,5 @@
 ---
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: calico-node
diff --git a/roles/network_plugin/calico/templates/calico-node.yml.j2 b/roles/network_plugin/calico/templates/calico-node.yml.j2
index 8a0ea9e5b473d5d3db2ad54b6952052c92651ff2..23e01430d51e5500a255ef314938d4dbe579d944 100644
--- a/roles/network_plugin/calico/templates/calico-node.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-node.yml.j2
@@ -204,6 +204,10 @@ spec:
 {% if kube_proxy_mode == 'ipvs' and kube_apiserver_node_port_range is defined %}
             - name: FELIX_KUBENODEPORTRANGES
               value: "{{ kube_apiserver_node_port_range.split('-')[0] }}:{{ kube_apiserver_node_port_range.split('-')[1] }}"
+{% endif %}
+{% if calico_version is version('v3.8.1', '>=') %}
+            - name: FELIX_IPTABLESBACKEND
+              value: "{{ calico_iptables_backend }}"
 {% endif %}
             # Prior to v3.2.1 iptables didn't acquire the lock, so Calico's own implementation of the lock should be used,
             # this is not required in later versions https://github.com/projectcalico/calico/issues/2179
@@ -269,10 +273,18 @@ spec:
               cpu: {{ calico_node_cpu_requests }}
               memory: {{ calico_node_memory_requests }}
           livenessProbe:
+{% if calico_version is version('v3.8.0', '<') %}
             httpGet:
               host: 127.0.0.1
               path: /liveness
               port: 9099
+{% else %}
+            exec:
+              command:
+              - /bin/calico-node
+              - -felix-live
+              - -bird-live
+{% endif %}
             initialDelaySeconds: 5
             failureThreshold: 6
           readinessProbe: