diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index cd2b1e0e33..880dbcb173 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -4,6 +4,7 @@ Changelog
 2.16.2 (xx.xx.xxxx) - IN DEVELOPMENT
 ~~~~~~~~~~~~~~~~~~~
 
+ * Update Jinja2 template support for Jinja2 3.x (Seb Brown)
  * Fix: Update django-treebeard dependency to 4.5.1 or above (Serafeim Papastefanos)
 
 
diff --git a/docs/releases/2.16.2.md b/docs/releases/2.16.2.md
index bbd8d6bad5..e4468633c6 100644
--- a/docs/releases/2.16.2.md
+++ b/docs/releases/2.16.2.md
@@ -11,3 +11,4 @@
 ### Bug fixes
 
  * Update django-treebeard dependency to 4.5.1 or above (Serafeim Papastefanos)
+ * Update Jinja2 template support for Jinja2 3.x (Seb Brown)
diff --git a/setup.py b/setup.py
index 81fcfd7867..5b891d4302 100755
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,7 @@ testing_extras = [
     'python-dateutil>=2.7',
     'pytz>=2014.7',
     'elasticsearch>=5.0,<6.0',
-    'Jinja2>=3.0,<4.0',
+    'Jinja2>=3.0,<3.2',
     'boto3>=1.16,<1.17',
     'freezegun>=0.3.8',
     'openpyxl>=2.6.4',
diff --git a/wagtail/admin/jinja2tags.py b/wagtail/admin/jinja2tags.py
index 121acf21a5..0df543f898 100644
--- a/wagtail/admin/jinja2tags.py
+++ b/wagtail/admin/jinja2tags.py
@@ -10,7 +10,7 @@ class WagtailUserbarExtension(Extension):
         super().__init__(environment)
 
         self.environment.globals.update({
-            'wagtailuserbar': jinja2.contextfunction(wagtailuserbar),
+            "wagtailuserbar": jinja2.pass_context(wagtailuserbar),
         })
 
 
diff --git a/wagtail/contrib/settings/jinja2tags.py b/wagtail/contrib/settings/jinja2tags.py
index ccf4a84d3a..1a18a07abd 100644
--- a/wagtail/contrib/settings/jinja2tags.py
+++ b/wagtail/contrib/settings/jinja2tags.py
@@ -57,7 +57,7 @@ class SiteSettings(dict):
         return out
 
 
-@jinja2.contextfunction
+@jinja2.pass_context
 def get_setting(context, model_string, use_default_site=False):
     if use_default_site:
         site = Site.objects.get(is_default_site=True)
diff --git a/wagtail/core/jinja2tags.py b/wagtail/core/jinja2tags.py
index a31c410de9..1db8f44b52 100644
--- a/wagtail/core/jinja2tags.py
+++ b/wagtail/core/jinja2tags.py
@@ -2,6 +2,7 @@ import jinja2
 import jinja2.nodes
 
 from jinja2.ext import Extension
+from markupsafe import Markup, escape
 
 from .templatetags.wagtailcore_tags import pageurl, richtext, slugurl, wagtail_site, wagtail_version
 
@@ -13,9 +14,9 @@ class WagtailCoreExtension(Extension):
         super().__init__(environment)
 
         self.environment.globals.update({
-            'pageurl': jinja2.contextfunction(pageurl),
-            'slugurl': jinja2.contextfunction(slugurl),
-            'wagtail_site': jinja2.contextfunction(wagtail_site),
+            'pageurl': jinja2.pass_context(pageurl),
+            'slugurl': jinja2.pass_context(slugurl),
+            'wagtail_site': jinja2.pass_context(wagtail_site),
             'wagtail_version': wagtail_version,
         })
         self.environment.filters.update({
@@ -62,9 +63,9 @@ class WagtailCoreExtension(Extension):
             result = value
 
         if context.eval_ctx.autoescape:
-            return jinja2.escape(result)
+            return escape(result)
         else:
-            return jinja2.Markup(result)
+            return Markup(result)
 
 
 # Nicer import names