diff --git a/django/contrib/admin/static/admin/css/forms.css b/django/contrib/admin/static/admin/css/forms.css
index fb91a24492..77985d5d34 100644
--- a/django/contrib/admin/static/admin/css/forms.css
+++ b/django/contrib/admin/static/admin/css/forms.css
@@ -83,7 +83,7 @@ form ul.inline li {
     height: 26px;
 }
 
-.aligned label + p, .aligned label + div.help {
+.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {
     padding: 6px 0;
     margin-top: 0;
     margin-bottom: 0;
diff --git a/django/contrib/admin/templates/admin/includes/fieldset.html b/django/contrib/admin/templates/admin/includes/fieldset.html
index 20f86f73b3..fce9966664 100644
--- a/django/contrib/admin/templates/admin/includes/fieldset.html
+++ b/django/contrib/admin/templates/admin/includes/fieldset.html
@@ -14,7 +14,7 @@
                     {% else %}
                         {{ field.label_tag }}
                         {% if field.is_readonly %}
-                            <p>{{ field.contents }}</p>
+                            <div class="readonly">{{ field.contents }}</div>
                         {% else %}
                             {{ field.field }}
                         {% endif %}
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index d26a6a0a51..ff40daa504 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -501,6 +501,15 @@ This works similar to ``settings.TIME_ZONE = None`` except that it also sets
 if there's a use case where you find you can't adapt your code to set a
 ``TIME_ZONE``.
 
+HTML changes in admin templates
+-------------------------------
+
+``<p class="help">`` is replaced with a ``<div>`` tag to allow including lists
+inside help text.
+
+Read-only fields are wrapped in ``<div class="readonly">...</div>`` instead of
+``<p>...</p>`` to allow any kind of HTML as the field's content.
+
 Miscellaneous
 -------------
 
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 0643448984..ae66e2e508 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -4598,11 +4598,15 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
         self.assertContains(response, "foo")
 
         # Multiline text in a readonly field gets <br /> tags
-        self.assertContains(response, "Multiline<br />test<br />string")
-        self.assertContains(response, "<p>Multiline<br />html<br />content</p>", html=True)
-        self.assertContains(response, "InlineMultiline<br />test<br />string")
+        self.assertContains(response, 'Multiline<br />test<br />string')
+        self.assertContains(response, '<div class="readonly">Multiline<br />html<br />content</div>', html=True)
+        self.assertContains(response, 'InlineMultiline<br />test<br />string')
         # Remove only this last line when the deprecation completes.
-        self.assertContains(response, "<p>Multiline<br />html<br />content<br />with allow tags</p>", html=True)
+        self.assertContains(
+            response,
+            '<div class="readonly">Multiline<br />html<br />content<br />with allow tags</div>',
+            html=True
+        )
 
         self.assertContains(response, formats.localize(datetime.date.today() - datetime.timedelta(days=7)))
 
@@ -4685,8 +4689,7 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
         """
         choice = Choice.objects.create(choice=None)
         response = self.client.get(reverse('admin:admin_views_choice_change', args=(choice.pk,)))
-        self.assertContains(response, '<p>No opinion</p>', html=True)
-        self.assertNotContains(response, '<p>(None)</p>')
+        self.assertContains(response, '<div class="readonly">No opinion</div>', html=True)
 
     def test_readonly_manytomany_backwards_ref(self):
         """
@@ -4705,7 +4708,7 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
         pizza.toppings.add(topping)
         response = self.client.get(reverse('admin:admin_views_pizza_change', args=(pizza.pk,)))
         self.assertContains(response, '<label>Toppings:</label>', html=True)
-        self.assertContains(response, '<p>Salami</p>', html=True)
+        self.assertContains(response, '<div class="readonly">Salami</div>', html=True)
 
     def test_readonly_onetoone_backwards_ref(self):
         """
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 447234209f..78b68e7768 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -419,8 +419,8 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
         response = self.client.get(reverse('admin:admin_widgets_album_change', args=(self.album.id,)))
         self.assertContains(
             response,
-            '<p><a href="%(STORAGE_URL)salbums/hybrid_theory.jpg">'
-            r'albums\hybrid_theory.jpg</a></p>' % {'STORAGE_URL': default_storage.url('')},
+            '<div class="readonly"><a href="%(STORAGE_URL)salbums/hybrid_theory.jpg">'
+            r'albums\hybrid_theory.jpg</a></div>' % {'STORAGE_URL': default_storage.url('')},
             html=True,
         )
         self.assertNotContains(
@@ -431,7 +431,7 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
         response = self.client.get(reverse('admin:admin_widgets_album_add'))
         self.assertContains(
             response,
-            '<p></p>',
+            '<div class="readonly"></div>',
             html=True,
         )