diff --git a/cinder/tests/unit/targets/test_base_iscsi_driver.py b/cinder/tests/unit/targets/test_base_iscsi_driver.py
index a9ea65812b3..0fdcb4e9893 100644
--- a/cinder/tests/unit/targets/test_base_iscsi_driver.py
+++ b/cinder/tests/unit/targets/test_base_iscsi_driver.py
@@ -158,6 +158,23 @@ class TestBaseISCSITargetDriver(tf.TargetDriverFixture):
                                                ['portal2'])
         self.assertEqual('portal:3260;portal2:3260,1 target 2', location)
 
+    def test_iscsi_location_IPv6(self):
+        ip = 'fd00:fd00:fd00:3000::12'
+        ip2 = 'fd00:fd00:fd00:3000::13'
+
+        location = self.target._iscsi_location(ip, 1, 'target', 2)
+        self.assertEqual('[%s]:3260,1 target 2' % ip, location)
+
+        location = self.target._iscsi_location(ip, 1, 'target', 2, [ip2])
+        self.assertEqual('[%s]:3260;[%s]:3260,1 target 2' % (ip, ip2),
+                         location)
+
+        # Mix of IPv6 (already with square brackets) and IPv4
+        ip = '[' + ip + ']'
+        location = self.target._iscsi_location(ip, 1, 'target', 2,
+                                               ['192.168.1.1'])
+        self.assertEqual(ip + ':3260;192.168.1.1:3260,1 target 2', location)
+
     def test_get_target_chap_auth(self):
         ctxt = context.get_admin_context()
         self.assertEqual(('otzL', '234Z'),
diff --git a/cinder/tests/unit/targets/test_scst_driver.py b/cinder/tests/unit/targets/test_scst_driver.py
index 067b0d5f37f..1e879d4fb39 100644
--- a/cinder/tests/unit/targets/test_scst_driver.py
+++ b/cinder/tests/unit/targets/test_scst_driver.py
@@ -231,3 +231,16 @@ class TestSCSTAdmDriver(tf.TargetDriverFixture):
                 'iqn.2010-10.org.openstack:testvol',
                 'ed2c2222-5fc0-11e4-aa15-123b93f75cba',
                 0, 1, self.fake_volumes_dir, None)
+
+    def test_iscsi_location(self):
+        location = self.target._iscsi_location('portal', 1, 'target', 2)
+        self.assertEqual('portal:3260,1 target 2', location)
+
+    def test_iscsi_location_IPv6(self):
+        ip = 'fd00:fd00:fd00:3000::12'
+        location = self.target._iscsi_location(ip, 1, 'target', 2)
+        self.assertEqual('[%s]:3260,1 target 2' % ip, location)
+
+        ip = '[' + ip + ']'
+        location = self.target._iscsi_location(ip, 1, 'target', 2)
+        self.assertEqual(ip + ':3260,1 target 2', location)
diff --git a/cinder/volume/targets/iscsi.py b/cinder/volume/targets/iscsi.py
index 67311aadbfa..03bf7ef7d54 100644
--- a/cinder/volume/targets/iscsi.py
+++ b/cinder/volume/targets/iscsi.py
@@ -300,7 +300,8 @@ class ISCSITarget(driver.Target):
     def _iscsi_location(self, ip, target, iqn, lun=None, ip_secondary=None):
         ip_secondary = ip_secondary or []
         port = self.configuration.target_port
-        portals = map(lambda x: "%s:%s" % (x, port), [ip] + ip_secondary)
+        portals = map(lambda x: "%s:%s" % (vutils.sanitize_host(x), port),
+                      [ip] + ip_secondary)
         return ("%(portals)s,%(target)s %(iqn)s %(lun)s"
                 % ({'portals': ";".join(portals),
                     'target': target, 'iqn': iqn, 'lun': lun}))
diff --git a/cinder/volume/targets/scst.py b/cinder/volume/targets/scst.py
index 3d6c2234a2a..dcd7833f4dd 100644
--- a/cinder/volume/targets/scst.py
+++ b/cinder/volume/targets/scst.py
@@ -231,7 +231,8 @@ class SCSTAdm(iscsi.ISCSITarget):
         return tid
 
     def _iscsi_location(self, ip, target, iqn, lun=None):
-        return "%s:%s,%s %s %s" % (ip, self.configuration.target_port,
+        return "%s:%s,%s %s %s" % (vutils.sanitize_host(ip),
+                                   self.configuration.target_port,
                                    target, iqn, lun)
 
     def _get_iscsi_name(self, volume):
diff --git a/cinder/volume/utils.py b/cinder/volume/utils.py
index 166d81cf00a..19df5de56bc 100644
--- a/cinder/volume/utils.py
+++ b/cinder/volume/utils.py
@@ -38,6 +38,7 @@ from oslo_concurrency import processutils
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import excutils
+from oslo_utils import netutils
 from oslo_utils import strutils
 from oslo_utils import timeutils
 from oslo_utils import units
@@ -1205,3 +1206,10 @@ def check_encryption_provider(db, volume, context):
         raise exception.VolumeDriverException(message=msg)
 
     return encryption
+
+
+def sanitize_host(host):
+    """Ensure IPv6 addresses are enclosed in [] for iSCSI portals."""
+    if netutils.is_valid_ipv6(host):
+        return '[%s]' % host
+    return host
diff --git a/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml b/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml
new file mode 100644
index 00000000000..dc38fef6d31
--- /dev/null
+++ b/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    LVM iSCSI driver fix for IPv6 addresses for the different targets, IET,
+    LIO, TGT, CXT, and SCST.