diff --git a/README.rst b/README.rst
index 5c167b76a..663864bb1 100644
--- a/README.rst
+++ b/README.rst
@@ -122,6 +122,12 @@ You'll find complete documentation on the shell by running
         secgroup-list-rules List rules for a security group.
         show                Show details about the given server.
         unrescue            Unrescue a server.
+        volume-attach       Attach a volume to a server.
+        volume-create       Add a new volume.
+        volume-delete       Remove a volume.
+        volume-detach       Detach a volume from a server.
+        volume-list         List all the volumes.
+        volume-show         Show details about a volume.
         zone                Show or edit a Child Zone
         zone-add            Add a Child Zone.
         zone-boot           Boot a server, considering Zones.
diff --git a/novaclient/v1_1/client.py b/novaclient/v1_1/client.py
index 81118c6c6..a46d6bbb8 100644
--- a/novaclient/v1_1/client.py
+++ b/novaclient/v1_1/client.py
@@ -7,6 +7,7 @@ from novaclient.v1_1 import security_group_rules
 from novaclient.v1_1 import security_groups
 from novaclient.v1_1 import servers
 from novaclient.v1_1 import quotas
+from novaclient.v1_1 import volumes
 from novaclient.v1_1 import zones
 
 
@@ -36,6 +37,7 @@ class Client(object):
         self.servers = servers.ServerManager(self)
 
         # extensions
+        self.volumes = volumes.VolumeManager(self)
         self.keypairs = keypairs.KeypairManager(self)
         self.zones = zones.ZoneManager(self)
         self.quotas = quotas.QuotaSetManager(self)
diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py
index 2dbd2030a..ef9d3d3bd 100644
--- a/novaclient/v1_1/shell.py
+++ b/novaclient/v1_1/shell.py
@@ -705,6 +705,94 @@ def do_remove_fixed_ip(cs, args):
     server.remove_fixed_ip(args.address)
 
 
+def _find_volume(cs, volume):
+    """Get a volume by ID."""
+    return utils.find_resource(cs.volumes, volume)
+
+
+def _print_volume(cs, volume):
+    utils.print_dict(volume._info)
+
+
+def _translate_volume_keys(collection):
+    convert = [('displayName', 'display_name')]
+    for item in collection:
+        keys = item.__dict__.keys()
+        for from_key, to_key in convert:
+            if from_key in keys and to_key not in keys:
+                setattr(item, to_key, item._info[from_key])
+
+
+def do_volume_list(cs, args):
+    """List all the volumes."""
+    volumes = cs.volumes.list()
+    _translate_volume_keys(volumes)
+
+    # Create a list of servers to which the volume is attached
+    for vol in volumes:
+        servers = [server.get('serverId') for server in vol.attachments]
+        setattr(vol, 'attached_to', ','.join(map(str, servers)))
+    utils.print_list(volumes, ['ID', 'Status', 'Display Name',
+                        'Size', 'Attached to'])
+
+
+@utils.arg('volume', metavar='<volume>', help='ID of the volume.')
+def do_volume_show(cs, args):
+    """Show details about a volume."""
+    volume = _find_volume(cs, args.volume)
+    _print_volume(cs, volume)
+
+
+@utils.arg('size',
+    metavar='<size>',
+    type=int,
+    help='Size of volume in GB')
+@utils.arg('--display_name', metavar='<display_name>',
+            help='Optional volume name. (Default=None)',
+            default=None)
+@utils.arg('--display_description', metavar='<display_description>',
+            help='Optional volume description. (Default=None)',
+            default=None)
+def do_volume_create(cs, args):
+    """Add a new volume."""
+    cs.volumes.create(args.size, args.display_name, args.display_description)
+
+
+@utils.arg('volume', metavar='<volume>', help='ID of the volume to delete.')
+def do_volume_delete(cs, args):
+    """Remove a volume."""
+    volume = _find_volume(cs, args.volume)
+    volume.delete()
+
+
+@utils.arg('server',
+    metavar='<server>',
+    help='Name or ID of server.')
+@utils.arg('volume',
+    metavar='<volume>',
+    type=int,
+    help='ID of the volume to attach.')
+@utils.arg('device', metavar='<device>',
+    help='Name of the device e.g. /dev/vdb.')
+def do_volume_attach(cs, args):
+    """Attach a volume to a server."""
+    cs.volumes.create_server_volume(_find_server(cs, args.server).id,
+                                        args.volume,
+                                        args.device)
+
+
+@utils.arg('server',
+    metavar='<server>',
+    help='Name or ID of server.')
+@utils.arg('attachment_id',
+    metavar='<volume>',
+    type=int,
+    help='Attachment ID of the volume.')
+def do_volume_detach(cs, args):
+    """Detach a volume from a server."""
+    cs.volumes.delete_server_volume(_find_server(cs, args.server).id,
+                                        args.attachment_id)
+
 def _print_floating_ip_list(floating_ips):
     utils.print_list(floating_ips, ['Ip', 'Instance Id', 'Fixed Ip'])