diff --git a/doc/source/command-objects/server.rst b/doc/source/command-objects/server.rst
index 4aeef4d056..f55e4139da 100644
--- a/doc/source/command-objects/server.rst
+++ b/doc/source/command-objects/server.rst
@@ -495,6 +495,21 @@ Resume server
 
     Server (name or ID)
 
+server shelve
+-------------
+
+Shelve server(s)
+
+.. program:: server shelve
+.. code:: bash
+
+    os server shelve
+        <server> [<server> ...]
+
+.. describe:: <server>
+
+    Server(s) to shelve (name or ID)
+
 server set
 ----------
 
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index e69699b173..ade351155f 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -182,6 +182,7 @@ Those actions with an opposite action are noted in parens if applicable.
 * ``revoke`` (``issue``) - revoke a token
 * ``save`` - download an object locally
 * ``set`` (``unset``) - set a property on the object, formerly called metadata
+* ``shelve`` (``unshelve``) - shelve one or more server
 * ``show`` - display detailed information about the specific object
 * ``start`` (``stop``) - start one or more servers
 * ``stop`` (``start``) - stop one or more servers
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index aa4569c3bb..bb74ae4321 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -1387,6 +1387,31 @@ class ShowServer(show.ShowOne):
         return zip(*sorted(six.iteritems(data)))
 
 
+class ShelveServer(command.Command):
+    """Shelve server(s)"""
+
+    log = logging.getLogger(__name__ + '.ShelveServer')
+
+    def get_parser(self, prog_name):
+        parser = super(ShelveServer, self).get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            nargs='+',
+            help=_('Server(s) to shelve (name or ID)'),
+        )
+        return parser
+
+    @utils.log_method(log)
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+        for server in parsed_args.server:
+            utils.find_resource(
+                compute_client.servers,
+                server,
+            ).shelve()
+
+
 class SshServer(command.Command):
     """Ssh to server"""
 
diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py
index 791a90abd1..61e098a827 100644
--- a/openstackclient/tests/compute/v2/test_server.py
+++ b/openstackclient/tests/compute/v2/test_server.py
@@ -766,3 +766,57 @@ class TestServerGeneral(testtools.TestCase):
                           server._get_ip_address, self.OLD, 'public', [4, 6])
         self.assertRaises(exceptions.CommandError,
                           server._get_ip_address, self.OLD, 'private', [6])
+
+
+class TestShelveServer(TestServer):
+
+    def setUp(self):
+        super(TestShelveServer, self).setUp()
+
+        # Get the command object to test
+        self.cmd = server.ShelveServer(self.app, None)
+
+        # Set shelve method to be tested.
+        self.methods = {
+            'shelve': None,
+        }
+
+    def setup_servers_mock(self, count=1):
+        servers = fakes.FakeServer.create_servers(methods=self.methods,
+                                                  count=count)
+
+        self.servers_mock.get = fakes.FakeServer.get_servers(servers, 1)
+
+        return servers
+
+    def test_shelve_one_server(self):
+        server = self.setup_servers_mock(1)[0]
+
+        arglist = [
+            server.id,
+        ]
+        verifylist = [
+            ('server', [server.id]),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+
+        server.shelve.assert_called_with()
+
+    def test_shelve_multi_servers(self):
+        servers = self.setup_servers_mock(3)
+        arglist = []
+        verifylist = []
+
+        for i in range(0, len(servers)):
+            arglist.append(servers[i].id)
+        verifylist = [
+            ('server', arglist),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+
+        for i in range(0, len(servers)):
+            servers[i].shelve.assert_called_with()
diff --git a/setup.cfg b/setup.cfg
index d79df17b84..6760e84d40 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -130,6 +130,7 @@ openstack.compute.v2 =
     server_resize = openstackclient.compute.v2.server:ResizeServer
     server_resume = openstackclient.compute.v2.server:ResumeServer
     server_set = openstackclient.compute.v2.server:SetServer
+    server_shelve = openstackclient.compute.v2.server:ShelveServer
     server_show = openstackclient.compute.v2.server:ShowServer
     server_ssh = openstackclient.compute.v2.server:SshServer
     server_start = openstackclient.compute.v2.server:StartServer