diff --git a/reviewboard/changedescs/evolutions/__init__.py b/reviewboard/changedescs/evolutions/__init__.py
index 0e988084bd66c8af8ca380a5ad0caa1a8b8df292..f8a56796b9e78c7ffdfd046be8089a80c2d4e3b8 100644
--- a/reviewboard/changedescs/evolutions/__init__.py
+++ b/reviewboard/changedescs/evolutions/__init__.py
@@ -9,4 +9,5 @@ if settings.DATABASES['default']['ENGINE'].endswith('mysql'):
 SEQUENCE.extend([
     'rich_text',
     'changedesc_user',
+    'extra_data',
 ])
diff --git a/reviewboard/changedescs/evolutions/extra_data.py b/reviewboard/changedescs/evolutions/extra_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6acfc92ec6bc5ceb791d28792ecf2d62879cfb2
--- /dev/null
+++ b/reviewboard/changedescs/evolutions/extra_data.py
@@ -0,0 +1,11 @@
+"""An evolution file that adds extra_data JSON field to the ChangeDescription
+model.
+"""
+
+from django_evolution.mutations import AddField
+from djblets.db.fields.json_field import JSONField
+
+
+MUTATIONS = [
+    AddField('ChangeDescription', 'extra_data', JSONField, null=True),
+]
diff --git a/reviewboard/changedescs/models.py b/reviewboard/changedescs/models.py
index 5d1246002026978867ecdd692859ba027b4f1a21..ea28adc318827065f9abe858c9a6e7c1d049ff2c 100644
--- a/reviewboard/changedescs/models.py
+++ b/reviewboard/changedescs/models.py
@@ -39,6 +39,7 @@ class ChangeDescription(models.Model):
     text = models.TextField(_("change text"), blank=True)
     rich_text = models.BooleanField(_("rich text"), default=False)
     fields_changed = JSONField(_("fields changed"))
+    extra_data = JSONField(null=True)
 
     def get_user(self, model=None):
         """Return the user associated with the change description.
