diff --git a/doc/source/enforcer.py b/doc/source/enforcer.py
index 6eea11e40..94fd8d3dc 100644
--- a/doc/source/enforcer.py
+++ b/doc/source/enforcer.py
@@ -33,7 +33,8 @@ class EnforcementError(errors.SphinxError):
 
 def get_proxy_methods():
     """Return a set of public names on all proxies"""
-    names = ["openstack.baremetal.v1._proxy",
+    names = ["openstack.accelerator.v2._proxy",
+             "openstack.baremetal.v1._proxy",
              "openstack.clustering.v1._proxy",
              "openstack.block_storage.v2._proxy",
              "openstack.compute.v2._proxy",
diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst
index 9daef05f2..9559f41de 100644
--- a/doc/source/user/index.rst
+++ b/doc/source/user/index.rst
@@ -95,6 +95,7 @@ control which services can be used.
 .. toctree::
    :maxdepth: 1
 
+   Accelerator <proxies/accelerator>
    Baremetal <proxies/baremetal>
    Baremetal Introspection <proxies/baremetal_introspection>
    Block Storage <proxies/block_storage>
@@ -129,6 +130,7 @@ The following services have exposed *Resource* classes.
 .. toctree::
    :maxdepth: 1
 
+   Accelerator <resources/accelerator/index>
    Baremetal <resources/baremetal/index>
    Baremetal Introspection <resources/baremetal_introspection/index>
    Block Storage <resources/block_storage/index>
diff --git a/doc/source/user/proxies/accelerator.rst b/doc/source/user/proxies/accelerator.rst
new file mode 100644
index 000000000..b5688a518
--- /dev/null
+++ b/doc/source/user/proxies/accelerator.rst
@@ -0,0 +1,51 @@
+Accelerator API
+===============
+
+.. automodule:: openstack.accelerator.v2._proxy
+
+The Accelerator Class
+---------------------
+
+The accelerator high-level interface is available through the ``accelerator``
+member of a :class:`~openstack.connection.Connection` object.
+The ``accelerator`` member will only be added if the service is detected.
+
+
+Device Operations
+^^^^^^^^^^^^^^^^^
+
+.. autoclass:: openstack.accelerator.v2._proxy.Proxy
+
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.get_device
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.devices
+
+Deployable Operations
+^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: openstack.accelerator.v2._proxy.Proxy
+
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.update_deployable
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.get_deployable
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.deployables
+
+Device Profile Operations
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: openstack.accelerator.v2._proxy.Proxy
+
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.create_device_profile
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.delete_device_profile
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.get_device_profile
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.device_profiles
+
+Accelerator Request Operations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: openstack.accelerator.v2._proxy.Proxy
+
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.create_accelerator_request
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.delete_accelerator_request
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.get_accelerator_request
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.accelerator_requests
+   .. automethod:: openstack.accelerator.v2._proxy.Proxy.update_accelerator_request
+
diff --git a/doc/source/user/resources/accelerator/index.rst b/doc/source/user/resources/accelerator/index.rst
new file mode 100644
index 000000000..5e09cf616
--- /dev/null
+++ b/doc/source/user/resources/accelerator/index.rst
@@ -0,0 +1,11 @@
+Accelerator v2 Resources
+========================
+
+.. toctree::
+   :maxdepth: 1
+
+   v2/device
+   v2/deployable
+   v2/device_profile
+   v2/accelerator_request
+
diff --git a/doc/source/user/resources/accelerator/v2/accelerator_request.rst b/doc/source/user/resources/accelerator/v2/accelerator_request.rst
new file mode 100644
index 000000000..172511407
--- /dev/null
+++ b/doc/source/user/resources/accelerator/v2/accelerator_request.rst
@@ -0,0 +1,13 @@
+openstack.accelerator.v2.accelerator_request
+============================================
+
+.. automodule:: openstack.accelerator.v2.accelerator_request
+
+The AcceleratorRequest Class
+----------------------------
+
+The ``AcceleratorRequest`` class inherits from
+:class:`~openstack.resource.Resource`.
+
+.. autoclass:: openstack.accelerator.v2.accelerator_request.AcceleratorRequest
+   :members:
diff --git a/doc/source/user/resources/accelerator/v2/deployable.rst b/doc/source/user/resources/accelerator/v2/deployable.rst
new file mode 100644
index 000000000..383795c2a
--- /dev/null
+++ b/doc/source/user/resources/accelerator/v2/deployable.rst
@@ -0,0 +1,13 @@
+openstack.accelerator.v2.deployable
+============================================
+
+.. automodule:: openstack.accelerator.v2.deployable
+
+The Deployable Class
+--------------------
+
+The ``Deployable`` class inherits from :class:`~openstack.resource.Resource`.
+
+.. autoclass:: openstack.accelerator.v2.deployable.Deployable
+   :members:
+
diff --git a/doc/source/user/resources/accelerator/v2/device.rst b/doc/source/user/resources/accelerator/v2/device.rst
new file mode 100644
index 000000000..943743546
--- /dev/null
+++ b/doc/source/user/resources/accelerator/v2/device.rst
@@ -0,0 +1,13 @@
+openstack.accelerator.v2.device
+============================================
+
+.. automodule:: openstack.accelerator.v2.device
+
+The Device Class
+--------------------
+
+The ``Device`` class inherits from :class:`~openstack.resource.Resource`.
+
+.. autoclass:: openstack.accelerator.v2.device.Device
+   :members:
+
diff --git a/doc/source/user/resources/accelerator/v2/device_profile.rst b/doc/source/user/resources/accelerator/v2/device_profile.rst
new file mode 100644
index 000000000..9849c7833
--- /dev/null
+++ b/doc/source/user/resources/accelerator/v2/device_profile.rst
@@ -0,0 +1,14 @@
+openstack.accelerator.v2.device_profile
+============================================
+
+.. automodule:: openstack.accelerator.v2.device_profile
+
+The DeviceProfile Class
+-----------------------
+
+The ``DeviceProfile`` class inherits from
+:class:`~openstack.resource.Resource`.
+
+.. autoclass:: openstack.accelerator.v2.device_profile.DeviceProfile
+   :members:
+
diff --git a/openstack/_services_mixin.py b/openstack/_services_mixin.py
index 5f8fbedf6..eb58e83b8 100644
--- a/openstack/_services_mixin.py
+++ b/openstack/_services_mixin.py
@@ -1,5 +1,6 @@
 # Generated file, to change, run tools/print-services.py
 from openstack import service_description
+from openstack.accelerator import accelerator_service
 from openstack.baremetal import baremetal_service
 from openstack.baremetal_introspection import baremetal_introspection_service
 from openstack.block_storage import block_storage_service
@@ -124,7 +125,7 @@ class ServicesMixin(object):
 
     function_engine = service_description.ServiceDescription(service_type='function-engine')
 
-    accelerator = service_description.ServiceDescription(service_type='accelerator')
+    accelerator = accelerator_service.AcceleratorService(service_type='accelerator')
 
     admin_logic = service_description.ServiceDescription(service_type='admin-logic')
     registration = admin_logic
diff --git a/openstack/accelerator/__init__.py b/openstack/accelerator/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/openstack/accelerator/accelerator_service.py b/openstack/accelerator/accelerator_service.py
new file mode 100644
index 000000000..9d7f1784a
--- /dev/null
+++ b/openstack/accelerator/accelerator_service.py
@@ -0,0 +1,21 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack import service_description
+from openstack.accelerator.v2 import _proxy as _proxy_v2
+
+
+class AcceleratorService(service_description.ServiceDescription):
+    """The accelerator service."""
+    supported_versions = {
+        '2': _proxy_v2.Proxy,
+    }
diff --git a/openstack/accelerator/v2/__init__.py b/openstack/accelerator/v2/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/openstack/accelerator/v2/_proxy.py b/openstack/accelerator/v2/_proxy.py
new file mode 100644
index 000000000..8be5ac754
--- /dev/null
+++ b/openstack/accelerator/v2/_proxy.py
@@ -0,0 +1,173 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from openstack import proxy
+from openstack.accelerator.v2 import deployable as _deployable
+from openstack.accelerator.v2 import device as _device
+from openstack.accelerator.v2 import device_profile as _device_profile
+from openstack.accelerator.v2 import accelerator_request as _arq
+
+
+class Proxy(proxy.Proxy):
+
+    def deployables(self, **query):
+        """Retrieve a generator of deployables.
+
+        :param kwargs query: Optional query parameters to be sent to
+            restrict the deployables to be returned.
+        :returns: A generator of deployable instances.
+        """
+        return self._list(_deployable.Deployable, **query)
+
+    def get_deployable(self, uuid, fields=None):
+        """Get a single deployable.
+
+        :param uuid: The value can be the UUID of a deployable.
+        :returns: One :class:`~openstack.accelerator.v2.deployable.Deployable`
+        :raises: :class:`~openstack.exceptions.ResourceNotFound` when no
+            deployable matching the criteria could be found.
+        """
+        return self._get(_deployable.Deployable, uuid)
+
+    def update_deployable(self, uuid, patch):
+        """Reconfig the FPGA with new bitstream.
+
+        :param uuid: The value can be the UUID of a deployable
+        :param patch: The infomation of to reconfig.
+        :returns: The results of FPGA reconfig.
+        """
+        return self._get_resource(_deployable.Deployable,
+                                  uuid).patch(self, patch)
+
+    def devices(self, **query):
+        """Retrieve a generator of devices.
+
+        :param kwargs query: Optional query parameters to be sent to
+            restrict the devices to be returned. Available parameters include:
+            * hostname: The hostname of the device.
+            * type: The type of the device.
+            * vendor: The vendor ID of the device.
+            * sort: A list of sorting keys separated by commas. Each sorting
+            key can optionally be attached with a sorting direction
+            modifier which can be ``asc`` or ``desc``.
+            * limit: Requests a specified size of returned items from the
+            query.  Returns a number of items up to the specified limit
+            value.
+            * marker: Specifies the ID of the last-seen item. Use the limit
+            parameter to make an initial limited request and use the ID of
+            the last-seen item from the response as the marker parameter
+            value in a subsequent limited request.
+        :returns: A generator of device instances.
+        """
+        return self._list(_device.Device, **query)
+
+    def get_device(self, uuid, fields=None):
+        """Get a single device.
+
+        :param uuid: The value can be the UUID of a device.
+        :returns: One :class:`~openstack.accelerator.v2.device.Device`
+        :raises: :class:`~openstack.exceptions.ResourceNotFound` when no
+            deployable matching the criteria could be found.
+        """
+        return self._get(_device.Device, uuid)
+
+    def device_profiles(self, **query):
+        """Retrieve a generator of device profiles.
+
+        :param kwargs query: Optional query parameters to be sent to
+            restrict the device profiles to be returned.
+        :returns: A generator of device profile instances.
+        """
+        return self._list(_device_profile.DeviceProfile, **query)
+
+    def create_device_profile(self, **attrs):
+        """Create a device_profiles.
+
+        :param kwargs attrs: a list of device_profiles.
+        :returns: The list of created device profiles
+        """
+        return self._create(_device_profile.DeviceProfile, **attrs)
+
+    def delete_device_profile(self, name_or_id, ignore_missing=True):
+        """Delete an device profile
+
+        :param name_or_id: The value can be either the ID of
+            an device profile.
+        :param bool ignore_missing: When set to ``False``
+            :class:`~openstack.exceptions.ResourceNotFound` will be
+            raised when the device profile does not exist.
+            When set to ``True``, no exception will be set when
+            attempting to delete a nonexistent device profile.
+        :returns: ``None``
+        """
+        return self._delete(_device_profile.DeviceProfile,
+                            name_or_id, ignore_missing=ignore_missing)
+
+    def get_device_profile(self, uuid, fields=None):
+        """Get a single device profile.
+
+        :param uuid: The value can be the UUID of a device profile.
+        :returns: One :class:
+            `~openstack.accelerator.v2.device_profile.DeviceProfile`
+        :raises: :class:`~openstack.exceptions.ResourceNotFound` when no
+            device profile matching the criteria could be found.
+        """
+        return self._get(_device_profile.DeviceProfile, uuid)
+
+    def accelerator_requests(self, **query):
+        """Retrieve a generator of accelerator requests.
+
+        :param kwargs query: Optional query parameters to be sent to
+            restrict the accelerator requests to be returned.
+        :returns: A generator of accelerator request instances.
+        """
+        return self._list(_arq.AcceleratorRequest, **query)
+
+    def create_accelerator_request(self, **attrs):
+        """Create an ARQs for a single device profile.
+
+        :param kwargs attrs: request body.
+        """
+        return self._create(_arq.AcceleratorRequest, **attrs)
+
+    def delete_accelerator_request(self, name_or_id, ignore_missing=True):
+        """Delete an device profile
+        :param name_or_id: The value can be either the ID of
+        an accelerator request.
+        :param bool ignore_missing: When set to ``False``
+        :class:`~openstack.exceptions.ResourceNotFound` will be
+        raised when the device profile does not exist.
+        When set to ``True``, no exception will be set when
+        attempting to delete a nonexistent accelerator request.
+        :returns: ``None``
+        """
+        return self._delete(_arq.AcceleratorRequest, name_or_id,
+                            ignore_missing=ignore_missing)
+
+    def get_accelerator_request(self, uuid, fields=None):
+        """Get a single accelerator request.
+        :param uuid: The value can be the UUID of a accelerator request.
+        :returns: One :class:
+        `~openstack.accelerator.v2.accelerator_request.AcceleratorRequest`
+        :raises: :class:`~openstack.exceptions.ResourceNotFound` when no
+        accelerator request matching the criteria could be found.
+        """
+        return self._get(_arq.AcceleratorRequest, uuid)
+
+    def update_accelerator_request(self, uuid, properties):
+        """Bind/Unbind an accelerator to VM.
+        :param uuid: The uuid of the accelerator_request to be binded/unbinded.
+        :param properties: The info of VM
+        that will bind/unbind the accelerator.
+        :returns: True if bind/unbind succeeded, False otherwise.
+        """
+        return self._get_resource(_arq.AcceleratorRequest,
+                                  uuid).patch(self, properties)
diff --git a/openstack/accelerator/v2/accelerator_request.py b/openstack/accelerator/v2/accelerator_request.py
new file mode 100644
index 000000000..b45bed453
--- /dev/null
+++ b/openstack/accelerator/v2/accelerator_request.py
@@ -0,0 +1,98 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack import resource
+from openstack import exceptions
+
+
+class AcceleratorRequest(resource.Resource):
+    resource_key = 'arq'
+    resources_key = 'arqs'
+    base_path = '/accelerator_requests'
+
+    # capabilities
+    allow_create = True
+    allow_fetch = True
+    allow_delete = True
+    allow_list = True
+    #: Allow patch operation for binding.
+    allow_patch = True
+
+    #: The device address associated with this ARQ (if any)
+    attach_handle_info = resource.Body('attach_handle_info')
+    #: The type of attach handle (e.g. PCI, mdev...)
+    attach_handle_type = resource.Body('attach_handle_type')
+    #: The name of the device profile
+    device_profile_name = resource.Body('device_profile_name')
+    #: The id of the device profile group
+    device_profile_group_id = resource.Body('device_profile_group_id')
+    #: The UUID of the bound device RP (if any)
+    device_rp_uuid = resource.Body('device_rp_uuid')
+    #: The host name to which ARQ is bound. (if any)
+    hostname = resource.Body('hostname')
+    #: The UUID of the instance associated with this ARQ (if any)
+    instance_uuid = resource.Body('instance_uuid')
+    #: The state of the ARQ
+    state = resource.Body('state')
+    #: The UUID of the ARQ
+    uuid = resource.Body('uuid', alternate_id=True)
+
+    def _convert_patch(self, patch):
+        # This overrides the default behavior of _convert_patch because
+        # the PATCH method consumes JSON, its key is the ARQ uuid
+        # and its value is an ordinary JSON patch. spec:
+        # https://specs.openstack.org/openstack/cyborg-specs/specs/train/approved/cyborg-api
+
+        converted = super(AcceleratorRequest, self)._convert_patch(patch)
+        converted = {self.id: converted}
+        return converted
+
+    def patch(self, session, patch=None, prepend_key=True, has_body=True,
+              retry_on_conflict=None, base_path=None):
+        # This overrides the default behavior of patch because
+        # the PATCH method consumes a dict rather than a list. spec:
+        # https://specs.openstack.org/openstack/cyborg-specs/specs/train/approved/cyborg-api
+
+        # The id cannot be dirty for an commit
+        self._body._dirty.discard("id")
+
+        # Only try to update if we actually have anything to commit.
+        if not patch and not self.requires_commit:
+            return self
+
+        if not self.allow_patch:
+            raise exceptions.MethodNotSupported(self, "patch")
+
+        request = self._prepare_request(prepend_key=prepend_key,
+                                        base_path=base_path, patch=True)
+        microversion = self._get_microversion_for(session, 'patch')
+        if patch:
+            request.body = self._convert_patch(patch)
+
+        return self._commit(session, request, 'PATCH', microversion,
+                            has_body=has_body,
+                            retry_on_conflict=retry_on_conflict)
+
+    def _consume_attrs(self, mapping, attrs):
+        # This overrides the default behavior of _consume_attrs because
+        # cyborg api returns an ARQ as list. spec:
+        # https://specs.openstack.org/openstack/cyborg-specs/specs/train/approved/cyborg-api
+        if isinstance(self, AcceleratorRequest):
+            if self.resources_key in attrs:
+                attrs = attrs[self.resources_key][0]
+        return super(AcceleratorRequest, self)._consume_attrs(mapping, attrs)
+
+    def create(self, session, base_path=None):
+        # This overrides the default behavior of resource creation because
+        # cyborg doesn't accept resource_key in its request.
+        return super(AcceleratorRequest, self).create(
+            session, prepend_key=False, base_path=base_path)
diff --git a/openstack/accelerator/v2/deployable.py b/openstack/accelerator/v2/deployable.py
new file mode 100644
index 000000000..ebfee3197
--- /dev/null
+++ b/openstack/accelerator/v2/deployable.py
@@ -0,0 +1,66 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from openstack import exceptions
+from openstack import resource
+
+
+class Deployable(resource.Resource):
+    resource_key = 'deployable'
+    resources_key = 'deployables'
+    base_path = '/deployables'
+    # capabilities
+    allow_create = False
+    allow_fetch = True
+    allow_commit = False
+    allow_delete = False
+    allow_list = True
+    allow_patch = True
+    #: The timestamp when this deployable was created.
+    created_at = resource.Body('created_at')
+    #: The device_id of the deployable.
+    device_id = resource.Body('device_id')
+    #: The UUID of the deployable.
+    id = resource.Body('uuid', alternate_id=True)
+    #: The name of the deployable.
+    name = resource.Body('name')
+    #: The num_accelerator of the deployable.
+    num_accelerators = resource.Body('num_accelerators')
+    #: The parent_id of the deployable.
+    parent_id = resource.Body('parent_id')
+    #: The root_id of the deployable.
+    root_id = resource.Body('root_id')
+    #: The timestamp when this deployable was updated.
+    updated_at = resource.Body('updated_at')
+
+    def _commit(self, session, request, method, microversion, has_body=True,
+                retry_on_conflict=None):
+        session = self._get_session(session)
+        kwargs = {}
+        retriable_status_codes = set(session.retriable_status_codes or ())
+        if retry_on_conflict:
+            kwargs['retriable_status_codes'] = retriable_status_codes | {409}
+        elif retry_on_conflict is not None and retriable_status_codes:
+            # The baremetal proxy defaults to retrying on conflict, allow
+            # overriding it via an explicit retry_on_conflict=False.
+            kwargs['retriable_status_codes'] = retriable_status_codes - {409}
+        try:
+            call = getattr(session, method.lower())
+        except AttributeError:
+            raise exceptions.ResourceFailure(
+                msg="Invalid commit method: %s" % method)
+        request.url = request.url + "/program"
+        response = call(request.url, json=request.body,
+                        headers=request.headers, microversion=microversion,
+                        **kwargs)
+        self.microversion = microversion
+        self._translate_response(response, has_body=has_body)
+        return self
diff --git a/openstack/accelerator/v2/device.py b/openstack/accelerator/v2/device.py
new file mode 100644
index 000000000..73799669d
--- /dev/null
+++ b/openstack/accelerator/v2/device.py
@@ -0,0 +1,44 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from openstack import resource
+
+
+class Device(resource.Resource):
+    resource_key = 'device'
+    resources_key = 'devices'
+    base_path = '/devices'
+    # capabilities
+    allow_create = False
+    allow_fetch = True
+    allow_commit = False
+    allow_delete = False
+    allow_list = True
+    #: The timestamp when this device was created.
+    created_at = resource.Body('created_at')
+    #: The hostname of the device.
+    hostname = resource.Body('hostname')
+    #: The ID of the device.
+    id = resource.Body('id')
+    #: The model of the device.
+    model = resource.Body('model')
+    #: The std board information of the device.
+    std_board_info = resource.Body('std_board_info')
+    #: The type of the device.
+    type = resource.Body('type')
+    #: The timestamp when this device was updated.
+    updated_at = resource.Body('updated_at')
+    #: The UUID of the device.
+    uuid = resource.Body('uuid', alternate_id=True)
+    #: The vendor ID of the device.
+    vendor = resource.Body('vendor')
+    #: The vendor board information of the device.
+    vendor_board_info = resource.Body('vendor_board_info')
diff --git a/openstack/accelerator/v2/device_profile.py b/openstack/accelerator/v2/device_profile.py
new file mode 100644
index 000000000..a09f48167
--- /dev/null
+++ b/openstack/accelerator/v2/device_profile.py
@@ -0,0 +1,48 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from openstack import resource
+
+
+class DeviceProfile(resource.Resource):
+    resource_key = 'device_profile'
+    resources_key = 'device_profiles'
+    base_path = '/device_profiles'
+    # capabilities
+    allow_create = True
+    allow_fetch = True
+    allow_commit = False
+    allow_delete = True
+    allow_list = True
+
+    #: The timestamp when this device_profile was created.
+    created_at = resource.Body('created_at')
+    #: The groups of the device profile
+    groups = resource.Body('groups')
+    #: The name of the device profile
+    name = resource.Body('name')
+    #: The timestamp when this device_profile was updated.
+    updated_at = resource.Body('updated_at')
+    #: The uuid of the device profile
+    uuid = resource.Body('uuid', alternate_id=True)
+
+    # TODO(s_shogo): This implementation only treat [ DeviceProfile ], and
+    # cannot treat multiple DeviceProfiles in list.
+    def _prepare_request_body(self, patch, prepend_key):
+        body = super(DeviceProfile, self)._prepare_request_body(
+            patch, prepend_key)
+        return [body]
+
+    def create(self, session, base_path=None):
+        # This overrides the default behavior of resource creation because
+        # cyborg doesn't accept resource_key in its request.
+        return super(DeviceProfile, self).create(
+            session, prepend_key=False, base_path=base_path)
diff --git a/openstack/accelerator/version.py b/openstack/accelerator/version.py
new file mode 100644
index 000000000..692230a19
--- /dev/null
+++ b/openstack/accelerator/version.py
@@ -0,0 +1,27 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from openstack import resource
+
+
+class Version(resource.Resource):
+    resource_key = 'version'
+    resources_key = 'versions'
+    base_path = '/'
+
+    # capabilities
+    allow_list = True
+
+    # Properties
+    links = resource.Body('links')
+    status = resource.Body('status')
diff --git a/openstack/cloud/_accelerator.py b/openstack/cloud/_accelerator.py
new file mode 100644
index 000000000..b28ac1f6b
--- /dev/null
+++ b/openstack/cloud/_accelerator.py
@@ -0,0 +1,154 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# import types so that we can reference ListType in sphinx param declarations.
+# We can't just use list, because sphinx gets confused by
+# openstack.resource.Resource.list and openstack.resource2.Resource.list
+
+from openstack.cloud import _normalize
+
+
+class AcceleratorCloudMixin(_normalize.Normalizer):
+
+    def list_deployables(self, filters=None):
+        """List all available deployables.
+        :param filters: (optional) dict of filter conditions to push down
+        :returns: A list of deployable info.
+        """
+
+        # Translate None from search interface to empty {} for kwargs below
+        if not filters:
+            filters = {}
+        return list(self.accelerator.deployables(**filters))
+
+    def list_devices(self, filters=None):
+        """List all devices.
+        :param filters: (optional) dict of filter conditions to push down
+        :returns: A list of device info.
+        """
+
+        # Translate None from search interface to empty {} for kwargs below
+        if not filters:
+            filters = {}
+        return list(self.accelerator.devices(**filters))
+
+    def list_device_profiles(self, filters=None):
+        """List all device_profiles.
+        :param filters: (optional) dict of filter conditions to push down
+        :returns: A list of device profile info.
+        """
+
+        # Translate None from search interface to empty {} for kwargs below
+        if not filters:
+            filters = {}
+        return list(self.accelerator.device_profiles(**filters))
+
+    def create_device_profile(self, attrs):
+        """Create a device_profile.
+        :param attrs: The info of device_profile to be created.
+        :returns: A ``munch.Munch`` of the created device_profile.
+        """
+
+        return self.accelerator.create_device_profile(**attrs)
+
+    def delete_device_profile(self, name_or_id, filters):
+        """Delete a device_profile.
+        :param name_or_id: The Name(or uuid) of device_profile to be deleted.
+        :returns: True if delete succeeded, False otherwise.
+        """
+
+        device_profile = self.accelerator.get_device_profile(
+            name_or_id,
+            filters
+        )
+        if device_profile is None:
+            self.log.debug(
+                "device_profile %s not found for deleting",
+                name_or_id
+            )
+            return False
+
+        self.accelerator.delete_device_profile(name_or_id=name_or_id)
+
+        return True
+
+    def list_accelerator_requests(self, filters=None):
+        """List all accelerator_requests.
+        :param filters: (optional) dict of filter conditions to push down
+        :returns: A list of accelerator request info.
+        """
+
+        # Translate None from search interface to empty {} for kwargs below
+        if not filters:
+            filters = {}
+        return list(self.accelerator.accelerator_requests(**filters))
+
+    def delete_accelerator_request(self, name_or_id, filters):
+        """Delete a accelerator_request.
+        :param name_or_id: The Name(or uuid) of accelerator_request.
+        :returns: True if delete succeeded, False otherwise.
+        """
+
+        accelerator_request = self.accelerator.get_accelerator_request(
+            name_or_id,
+            filters
+        )
+        if accelerator_request is None:
+            self.log.debug(
+                "accelerator_request %s not found for deleting",
+                name_or_id
+            )
+            return False
+
+        self.accelerator.delete_accelerator_request(name_or_id=name_or_id)
+
+        return True
+
+    def create_accelerator_request(self, attrs):
+        """Create an accelerator_request.
+        :param attrs: The info of accelerator_request to be created.
+        :returns: A ``munch.Munch`` of the created accelerator_request.
+        """
+
+        return self.accelerator.create_accelerator_request(**attrs)
+
+    def bind_accelerator_request(self, uuid, properties):
+        """Bind an accelerator to VM.
+        :param uuid: The uuid of the accelerator_request to be binded.
+        :param properties: The info of VM that will bind the accelerator.
+        :returns: True if bind succeeded, False otherwise.
+        """
+
+        accelerator_request = self.accelerator.get_accelerator_request(uuid)
+        if accelerator_request is None:
+            self.log.debug(
+                "accelerator_request %s not found for unbinding", uuid
+            )
+            return False
+
+        return self.accelerator.update_accelerator_request(uuid, properties)
+
+    def unbind_accelerator_request(self, uuid, properties):
+        """Unbind an accelerator from VM.
+        :param uuid: The uuid of the accelerator_request to be unbinded.
+        :param properties: The info of VM that will unbind the accelerator.
+        :returns:True if unbind succeeded, False otherwise.
+        """
+
+        accelerator_request = self.accelerator.get_accelerator_request(uuid)
+        if accelerator_request is None:
+            self.log.debug(
+                "accelerator_request %s not found for unbinding", uuid
+            )
+            return False
+
+        return self.accelerator.update_accelerator_request(uuid, properties)
diff --git a/openstack/connection.py b/openstack/connection.py
index d77a81f9a..1fae88e40 100644
--- a/openstack/connection.py
+++ b/openstack/connection.py
@@ -186,6 +186,7 @@ import six
 from openstack import _log
 from openstack import _services_mixin
 from openstack.cloud import openstackcloud as _cloud
+from openstack.cloud import _accelerator
 from openstack.cloud import _baremetal
 from openstack.cloud import _block_storage
 from openstack.cloud import _compute
@@ -249,6 +250,7 @@ def from_config(cloud=None, config=None, options=None, **kwargs):
 class Connection(
     _services_mixin.ServicesMixin,
     _cloud._OpenStackCloudMixin,
+    _accelerator.AcceleratorCloudMixin,
     _baremetal.BaremetalCloudMixin,
     _block_storage.BlockStorageCloudMixin,
     _compute.ComputeCloudMixin,
@@ -385,6 +387,7 @@ class Connection(
         # Call the _*CloudMixin constructors while we work on
         # integrating things better.
         _cloud._OpenStackCloudMixin.__init__(self)
+        _accelerator.AcceleratorCloudMixin.__init__(self)
         _baremetal.BaremetalCloudMixin.__init__(self)
         _block_storage.BlockStorageCloudMixin.__init__(self)
         _clustering.ClusteringCloudMixin.__init__(self)
diff --git a/openstack/tests/unit/accelerator/__init__.py b/openstack/tests/unit/accelerator/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/openstack/tests/unit/accelerator/test_version.py b/openstack/tests/unit/accelerator/test_version.py
new file mode 100644
index 000000000..43d6378e7
--- /dev/null
+++ b/openstack/tests/unit/accelerator/test_version.py
@@ -0,0 +1,42 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack.tests.unit import base
+
+from openstack.accelerator import version
+
+IDENTIFIER = 'IDENTIFIER'
+EXAMPLE = {
+    'id': IDENTIFIER,
+    'links': '2',
+    'status': '3',
+}
+
+
+class TestVersion(base.TestCase):
+
+    def test_basic(self):
+        sot = version.Version()
+        self.assertEqual('version', sot.resource_key)
+        self.assertEqual('versions', sot.resources_key)
+        self.assertEqual('/', sot.base_path)
+        self.assertFalse(sot.allow_create)
+        self.assertFalse(sot.allow_fetch)
+        self.assertFalse(sot.allow_commit)
+        self.assertFalse(sot.allow_delete)
+        self.assertTrue(sot.allow_list)
+
+    def test_make_it(self):
+        sot = version.Version(**EXAMPLE)
+        self.assertEqual(EXAMPLE['id'], sot.id)
+        self.assertEqual(EXAMPLE['links'], sot.links)
+        self.assertEqual(EXAMPLE['status'], sot.status)
diff --git a/openstack/tests/unit/accelerator/v2/__init__.py b/openstack/tests/unit/accelerator/v2/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/openstack/tests/unit/accelerator/v2/test_accelerator_request.py b/openstack/tests/unit/accelerator/v2/test_accelerator_request.py
new file mode 100644
index 000000000..8b36a717f
--- /dev/null
+++ b/openstack/tests/unit/accelerator/v2/test_accelerator_request.py
@@ -0,0 +1,59 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack.tests.unit import base
+
+from openstack.accelerator.v2 import accelerator_request as arq
+
+FAKE_ID = '0725b527-e51a-41df-ad22-adad5f4546ad'
+FAKE_RP_UUID = 'f4b7fe6c-8ab4-4914-a113-547af022935b'
+FAKE_INSTANCE_UUID = '1ce4a597-9836-4e02-bea1-a3a6cbe7b9f9'
+FAKE_ATTACH_INFO_STR = '{"bus": "5e", '\
+    '"device": "00", '\
+    '"domain": "0000", '\
+    '"function": "1"}'
+
+FAKE = {
+    'uuid': FAKE_ID,
+    'device_profile_name': 'fake-devprof',
+    'device_profile_group_id': 0,
+    'device_rp_uuid': FAKE_RP_UUID,
+    'instance_uuid': FAKE_INSTANCE_UUID,
+    'attach_handle_type': 'PCI',
+    'attach_handle_info': FAKE_ATTACH_INFO_STR,
+}
+
+
+class TestAcceleratorRequest(base.TestCase):
+
+    def test_basic(self):
+        sot = arq.AcceleratorRequest()
+        self.assertEqual('arq', sot.resource_key)
+        self.assertEqual('arqs', sot.resources_key)
+        self.assertEqual('/accelerator_requests', sot.base_path)
+        self.assertTrue(sot.allow_create)
+        self.assertTrue(sot.allow_fetch)
+        self.assertFalse(sot.allow_commit)
+        self.assertTrue(sot.allow_delete)
+        self.assertTrue(sot.allow_list)
+        self.assertTrue(sot.allow_patch)
+
+    def test_make_it(self):
+        sot = arq.AcceleratorRequest(**FAKE)
+        self.assertEqual(FAKE_ID, sot.uuid)
+        self.assertEqual(FAKE['device_profile_name'], sot.device_profile_name)
+        self.assertEqual(FAKE['device_profile_group_id'],
+                         sot.device_profile_group_id)
+        self.assertEqual(FAKE_RP_UUID, sot.device_rp_uuid)
+        self.assertEqual(FAKE_INSTANCE_UUID, sot.instance_uuid)
+        self.assertEqual(FAKE['attach_handle_type'], sot.attach_handle_type)
+        self.assertEqual(FAKE_ATTACH_INFO_STR, sot.attach_handle_info)
diff --git a/openstack/tests/unit/accelerator/v2/test_deployable.py b/openstack/tests/unit/accelerator/v2/test_deployable.py
new file mode 100644
index 000000000..dcb0af554
--- /dev/null
+++ b/openstack/tests/unit/accelerator/v2/test_deployable.py
@@ -0,0 +1,52 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+import uuid
+
+from openstack.tests.unit import base
+
+from openstack.accelerator.v2 import deployable
+
+EXAMPLE = {
+    'uuid': uuid.uuid4(),
+    'created_at': '2019-08-09T12:14:57.233772',
+    'updated_at': '2019-08-09T12:15:57.233772',
+    'parent_id': '1',
+    'root_id': '1',
+    'name': 'test_name',
+    'num_accelerators': '1',
+    'device_id': '1',
+}
+
+
+class TestDeployable(base.TestCase):
+
+    def test_basic(self):
+        sot = deployable.Deployable()
+        self.assertEqual('deployable', sot.resource_key)
+        self.assertEqual('deployables', sot.resources_key)
+        self.assertEqual('/deployables', sot.base_path)
+        self.assertFalse(sot.allow_create)
+        self.assertTrue(sot.allow_fetch)
+        self.assertFalse(sot.allow_commit)
+        self.assertFalse(sot.allow_delete)
+        self.assertTrue(sot.allow_list)
+
+    def test_make_it(self):
+        sot = deployable.Deployable(**EXAMPLE)
+        self.assertEqual(EXAMPLE['uuid'], sot.id)
+        self.assertEqual(EXAMPLE['parent_id'], sot.parent_id)
+        self.assertEqual(EXAMPLE['root_id'], sot.root_id)
+        self.assertEqual(EXAMPLE['name'], sot.name)
+        self.assertEqual(EXAMPLE['num_accelerators'], sot.num_accelerators)
+        self.assertEqual(EXAMPLE['device_id'], sot.device_id)
+        self.assertEqual(EXAMPLE['created_at'], sot.created_at)
+        self.assertEqual(EXAMPLE['updated_at'], sot.updated_at)
diff --git a/openstack/tests/unit/accelerator/v2/test_device.py b/openstack/tests/unit/accelerator/v2/test_device.py
new file mode 100644
index 000000000..22b17b336
--- /dev/null
+++ b/openstack/tests/unit/accelerator/v2/test_device.py
@@ -0,0 +1,53 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+import uuid
+
+from openstack.tests.unit import base
+from openstack.accelerator.v2 import device
+
+EXAMPLE = {
+    'id': '1',
+    'uuid': uuid.uuid4(),
+    'created_at': '2019-08-09T12:14:57.233772',
+    'updated_at': '2019-08-09T12:15:57.233772',
+    'type': 'test_type',
+    'vendor': '0x8086',
+    'model': 'test_model',
+    'std_board_info': '{"product_id": "0x09c4"}',
+    'vendor_board_info': 'test_vb_info',
+}
+
+
+class TestDevice(base.TestCase):
+
+    def test_basic(self):
+        sot = device.Device()
+        self.assertEqual('device', sot.resource_key)
+        self.assertEqual('devices', sot.resources_key)
+        self.assertEqual('/devices', sot.base_path)
+        self.assertFalse(sot.allow_create)
+        self.assertTrue(sot.allow_fetch)
+        self.assertFalse(sot.allow_commit)
+        self.assertFalse(sot.allow_delete)
+        self.assertTrue(sot.allow_list)
+
+    def test_make_it(self):
+        sot = device.Device(**EXAMPLE)
+        self.assertEqual(EXAMPLE['id'], sot.id)
+        self.assertEqual(EXAMPLE['uuid'], sot.uuid)
+        self.assertEqual(EXAMPLE['type'], sot.type)
+        self.assertEqual(EXAMPLE['vendor'], sot.vendor)
+        self.assertEqual(EXAMPLE['model'], sot.model)
+        self.assertEqual(EXAMPLE['std_board_info'], sot.std_board_info)
+        self.assertEqual(EXAMPLE['vendor_board_info'], sot.vendor_board_info)
+        self.assertEqual(EXAMPLE['created_at'], sot.created_at)
+        self.assertEqual(EXAMPLE['updated_at'], sot.updated_at)
diff --git a/openstack/tests/unit/accelerator/v2/test_device_profile.py b/openstack/tests/unit/accelerator/v2/test_device_profile.py
new file mode 100644
index 000000000..f1708713b
--- /dev/null
+++ b/openstack/tests/unit/accelerator/v2/test_device_profile.py
@@ -0,0 +1,54 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack.tests.unit import base
+
+from openstack.accelerator.v2 import device_profile
+
+
+FAKE = {
+    "id": 1,
+    "uuid": u"a95e10ae-b3e3-4eab-a513-1afae6f17c51",
+    "name": u'afaas_example_1',
+    "groups": [
+        {"resources:ACCELERATOR_FPGA": "1",
+         "trait:CUSTOM_FPGA_INTEL_PAC_ARRIA10": "required",
+         "trait:CUSTOM_FUNCTION_ID_3AFB": "required",
+         },
+        {"resources:CUSTOM_ACCELERATOR_FOO": "2",
+         "resources:CUSTOM_MEMORY": "200",
+         "trait:CUSTOM_TRAIT_ALWAYS": "required",
+         }
+    ]
+}
+
+
+class TestDeviceProfile(base.TestCase):
+
+    def test_basic(self):
+        sot = device_profile.DeviceProfile()
+        self.assertEqual('device_profile', sot.resource_key)
+        self.assertEqual('device_profiles', sot.resources_key)
+        self.assertEqual('/device_profiles', sot.base_path)
+        self.assertTrue(sot.allow_create)
+        self.assertTrue(sot.allow_fetch)
+        self.assertFalse(sot.allow_commit)
+        self.assertTrue(sot.allow_delete)
+        self.assertTrue(sot.allow_list)
+        self.assertFalse(sot.allow_patch)
+
+    def test_make_it(self):
+        sot = device_profile.DeviceProfile(**FAKE)
+        self.assertEqual(FAKE['id'], sot.id)
+        self.assertEqual(FAKE['uuid'], sot.uuid)
+        self.assertEqual(FAKE['name'], sot.name)
+        self.assertEqual(FAKE['groups'], sot.groups)
diff --git a/openstack/tests/unit/accelerator/v2/test_proxy.py b/openstack/tests/unit/accelerator/v2/test_proxy.py
new file mode 100644
index 000000000..b9fd45867
--- /dev/null
+++ b/openstack/tests/unit/accelerator/v2/test_proxy.py
@@ -0,0 +1,66 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack.accelerator.v2 import _proxy
+from openstack.accelerator.v2 import deployable
+from openstack.accelerator.v2 import device_profile
+from openstack.accelerator.v2 import accelerator_request
+from openstack.tests.unit import test_proxy_base as test_proxy_base
+
+
+class TestAcceleratorProxy(test_proxy_base.TestProxyBase):
+    def setUp(self):
+        super(TestAcceleratorProxy, self).setUp()
+        self.proxy = _proxy.Proxy(self.session)
+
+    def test_list_deployables(self):
+        self.verify_list(self.proxy.deployables, deployable.Deployable)
+
+    def test_list_device_profile(self):
+        self.verify_list(self.proxy.device_profiles,
+                         device_profile.DeviceProfile)
+
+    def test_create_device_profile(self):
+        self.verify_create(self.proxy.create_device_profile,
+                           device_profile.DeviceProfile)
+
+    def test_delete_device_profile(self):
+        self.verify_delete(self.proxy.delete_device_profile,
+                           device_profile.DeviceProfile, False)
+
+    def test_delete_device_profile_ignore(self):
+        self.verify_delete(self.proxy.delete_device_profile,
+                           device_profile.DeviceProfile, True)
+
+    def test_get_device_profile(self):
+        self.verify_get(self.proxy.get_device_profile,
+                        device_profile.DeviceProfile)
+
+    def test_list_accelerator_request(self):
+        self.verify_list(self.proxy.accelerator_requests,
+                         accelerator_request.AcceleratorRequest)
+
+    def test_create_accelerator_request(self):
+        self.verify_create(self.proxy.create_accelerator_request,
+                           accelerator_request.AcceleratorRequest)
+
+    def test_delete_accelerator_request(self):
+        self.verify_delete(self.proxy.delete_accelerator_request,
+                           accelerator_request.AcceleratorRequest, False)
+
+    def test_delete_accelerator_request_ignore(self):
+        self.verify_delete(self.proxy.delete_accelerator_request,
+                           accelerator_request.AcceleratorRequest, True)
+
+    def test_get_accelerator_request(self):
+        self.verify_get(self.proxy.get_accelerator_request,
+                        accelerator_request.AcceleratorRequest)
diff --git a/openstack/tests/unit/base.py b/openstack/tests/unit/base.py
index 9bb7a4d03..d39c265a9 100644
--- a/openstack/tests/unit/base.py
+++ b/openstack/tests/unit/base.py
@@ -564,6 +564,12 @@ class TestCase(base.TestCase):
                 compute_version_json, compute_discovery_url),
         ])
 
+    def get_cyborg_discovery_mock_dict(self):
+        discovery_fixture = os.path.join(
+            self.fixtures_directory, "accelerator.json")
+        return dict(method='GET', uri="https://accelerator.example.com/",
+                    text=open(discovery_fixture, 'r').read())
+
     def use_glance(
             self, image_version_json='image-version.json',
             image_discovery_url='https://image.example.com/'):
@@ -611,6 +617,15 @@ class TestCase(base.TestCase):
         self.__do_register_uris([
             self.get_senlin_discovery_mock_dict()])
 
+    def use_cyborg(self):
+        # NOTE(s_shogo): This method is only meant to be used in "setUp"
+        # where the ordering of the url being registered is tightly controlled
+        # if the functionality of .use_cyborg is meant to be used during an
+        # actual test case, use .get_cyborg_discovery_mock and apply to the
+        # right location in the mock_uris when calling .register_uris
+        self.__do_register_uris([
+            self.get_cyborg_discovery_mock_dict()])
+
     def register_uris(self, uri_mock_list=None):
         """Mock a list of URIs and responses via requests mock.
 
diff --git a/openstack/tests/unit/cloud/test_accelerator.py b/openstack/tests/unit/cloud/test_accelerator.py
new file mode 100644
index 000000000..5b09a56e8
--- /dev/null
+++ b/openstack/tests/unit/cloud/test_accelerator.py
@@ -0,0 +1,328 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from openstack.tests.unit import base
+import copy
+import uuid
+
+DEP_UUID = uuid.uuid4().hex
+DEP_DICT = {
+    'uuid': DEP_UUID,
+    'name': 'dep_name',
+    'parent_id': None,
+    'root_id': 1,
+    'num_accelerators': 4,
+    'device_id': 0
+}
+
+DEV_UUID = uuid.uuid4().hex
+DEV_DICT = {
+    'id': 1,
+    'uuid': DEV_UUID,
+    'name': 'dev_name',
+    'type': 'test_type',
+    'vendor': '0x8086',
+    'model': 'test_model',
+    'std_board_info': '{"product_id": "0x09c4"}',
+    'vendor_board_info': 'test_vb_info',
+}
+
+DEV_PROF_UUID = uuid.uuid4().hex
+DEV_PROF_GROUPS = [
+    {"resources:ACCELERATOR_FPGA": "1",
+     "trait:CUSTOM_FPGA_INTEL_PAC_ARRIA10": "required",
+     "trait:CUSTOM_FUNCTION_ID_3AFB": "required",
+     },
+    {"resources:CUSTOM_ACCELERATOR_FOO": "2",
+     "resources:CUSTOM_MEMORY": "200",
+     "trait:CUSTOM_TRAIT_ALWAYS": "required",
+     }
+]
+DEV_PROF_DICT = {
+    "id": 1,
+    "uuid": DEV_PROF_UUID,
+    "name": 'afaas_example_1',
+    "groups": DEV_PROF_GROUPS,
+}
+
+NEW_DEV_PROF_DICT = copy.copy(DEV_PROF_DICT)
+
+ARQ_UUID = uuid.uuid4().hex
+ARQ_DEV_RP_UUID = uuid.uuid4().hex
+ARQ_INSTANCE_UUID = uuid.uuid4().hex
+ARQ_ATTACH_INFO_STR = '{"bus": "5e", '\
+    '"device": "00", '\
+    '"domain": "0000", '\
+    '"function": "1"}'
+ARQ_DICT = {
+    'uuid': ARQ_UUID,
+    'hostname': 'test_hostname',
+    'device_profile_name': 'fake-devprof',
+    'device_profile_group_id': 0,
+    'device_rp_uuid': ARQ_DEV_RP_UUID,
+    'instance_uuid': ARQ_INSTANCE_UUID,
+    'attach_handle_type': 'PCI',
+    'attach_handle_info': ARQ_ATTACH_INFO_STR,
+}
+
+NEW_ARQ_DICT = copy.copy(ARQ_DICT)
+
+
+class TestAccelerator(base.TestCase):
+    def setUp(self):
+        super(TestAccelerator, self).setUp()
+        self.use_cyborg()
+
+    def test_list_deployables(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'deployables']),
+                 json={'deployables': [DEP_DICT]}
+                 ),
+        ])
+        dep_list = self.cloud.list_deployables()
+        self.assertEqual(len(dep_list), 1)
+        self.assertEqual(dep_list[0].id, DEP_DICT['uuid'])
+        self.assertEqual(dep_list[0].name, DEP_DICT['name'])
+        self.assertEqual(dep_list[0].parent_id, DEP_DICT['parent_id'])
+        self.assertEqual(dep_list[0].root_id, DEP_DICT['root_id'])
+        self.assertEqual(dep_list[0].num_accelerators,
+                         DEP_DICT['num_accelerators'])
+        self.assertEqual(dep_list[0].device_id, DEP_DICT['device_id'])
+        self.assert_calls()
+
+    def test_list_devices(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'devices']),
+                 json={'devices': [DEV_DICT]}
+                 ),
+        ])
+        dev_list = self.cloud.list_devices()
+        self.assertEqual(len(dev_list), 1)
+        self.assertEqual(dev_list[0].id, DEV_DICT['id'])
+        self.assertEqual(dev_list[0].uuid, DEV_DICT['uuid'])
+        self.assertEqual(dev_list[0].name, DEV_DICT['name'])
+        self.assertEqual(dev_list[0].type, DEV_DICT['type'])
+        self.assertEqual(dev_list[0].vendor, DEV_DICT['vendor'])
+        self.assertEqual(dev_list[0].model, DEV_DICT['model'])
+        self.assertEqual(dev_list[0].std_board_info,
+                         DEV_DICT['std_board_info'])
+        self.assertEqual(dev_list[0].vendor_board_info,
+                         DEV_DICT['vendor_board_info'])
+        self.assert_calls()
+
+    def test_list_device_profiles(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'device_profiles']),
+                 json={'device_profiles': [DEV_PROF_DICT]}
+                 ),
+        ])
+        dev_prof_list = self.cloud.list_device_profiles()
+        self.assertEqual(len(dev_prof_list), 1)
+        self.assertEqual(dev_prof_list[0].id, DEV_PROF_DICT['id'])
+        self.assertEqual(dev_prof_list[0].uuid, DEV_PROF_DICT['uuid'])
+        self.assertEqual(dev_prof_list[0].name, DEV_PROF_DICT['name'])
+        self.assertEqual(dev_prof_list[0].groups, DEV_PROF_DICT['groups'])
+        self.assert_calls()
+
+    def test_create_device_profile(self):
+        self.register_uris([
+            dict(method='POST',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'device_profiles']),
+                 json=NEW_DEV_PROF_DICT)
+        ])
+
+        attrs = {
+            'name': NEW_DEV_PROF_DICT['name'],
+            'groups': NEW_DEV_PROF_DICT['groups']
+        }
+
+        self.assertTrue(
+            self.cloud.create_device_profile(
+                attrs
+            )
+        )
+        self.assert_calls()
+
+    def test_delete_device_profile(self, filters=None):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'device_profiles', DEV_PROF_DICT['name']]),
+                 json={"device_profiles": [DEV_PROF_DICT]}),
+            dict(method='DELETE',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'device_profiles', DEV_PROF_DICT['name']]),
+                 json=DEV_PROF_DICT)
+
+        ])
+        self.assertTrue(
+            self.cloud.delete_device_profile(
+                DEV_PROF_DICT['name'],
+                filters
+            )
+        )
+        self.assert_calls()
+
+    def test_list_accelerator_requests(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests']),
+                 json={'arqs': [ARQ_DICT]}
+                 ),
+        ])
+        arq_list = self.cloud.list_accelerator_requests()
+        self.assertEqual(len(arq_list), 1)
+        self.assertEqual(arq_list[0].uuid, ARQ_DICT['uuid'])
+        self.assertEqual(arq_list[0].device_profile_name,
+                         ARQ_DICT['device_profile_name'])
+        self.assertEqual(arq_list[0].device_profile_group_id,
+                         ARQ_DICT['device_profile_group_id'])
+        self.assertEqual(arq_list[0].device_rp_uuid,
+                         ARQ_DICT['device_rp_uuid'])
+        self.assertEqual(arq_list[0].instance_uuid,
+                         ARQ_DICT['instance_uuid'])
+        self.assertEqual(arq_list[0].attach_handle_type,
+                         ARQ_DICT['attach_handle_type'])
+        self.assertEqual(arq_list[0].attach_handle_info,
+                         ARQ_DICT['attach_handle_info'])
+        self.assert_calls()
+
+    def test_create_accelerator_request(self):
+        self.register_uris([
+            dict(method='POST',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests']),
+                 json=NEW_ARQ_DICT
+                 ),
+        ])
+
+        attrs = {
+            'device_profile_name': NEW_ARQ_DICT['device_profile_name'],
+            'device_profile_group_id': NEW_ARQ_DICT['device_profile_group_id']
+        }
+
+        self.assertTrue(
+            self.cloud.create_accelerator_request(
+                attrs
+            )
+        )
+        self.assert_calls()
+
+    def test_delete_accelerator_request(self, filters=None):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json={"accelerator_requests": [ARQ_DICT]}),
+            dict(method='DELETE',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json=ARQ_DICT)
+
+        ])
+        self.assertTrue(
+            self.cloud.delete_accelerator_request(
+                ARQ_DICT['uuid'],
+                filters
+            )
+        )
+        self.assert_calls()
+
+    def test_bind_accelerator_request(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json={"accelerator_requests": [ARQ_DICT]}),
+            dict(method='PATCH',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json=ARQ_DICT)
+        ])
+        properties = [{'path': '/hostname',
+                       'value': ARQ_DICT['hostname'],
+                       'op': 'add'},
+                      {'path': '/instance_uuid',
+                       'value': ARQ_DICT['instance_uuid'],
+                       'op': 'add'},
+                      {'path': '/device_rp_uuid',
+                       'value': ARQ_DICT['device_rp_uuid'],
+                       'op': 'add'}]
+
+        self.assertTrue(
+            self.cloud.bind_accelerator_request(
+                ARQ_DICT['uuid'], properties
+            )
+        )
+        self.assert_calls()
+
+    def test_unbind_accelerator_request(self):
+        self.register_uris([
+            dict(method='GET',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json={"accelerator_requests": [ARQ_DICT]}),
+            dict(method='PATCH',
+                 uri=self.get_mock_url(
+                     'accelerator',
+                     'public',
+                     append=['v2', 'accelerator_requests', ARQ_DICT['uuid']]),
+                 json=ARQ_DICT)
+        ])
+
+        properties = [{'path': '/hostname',
+                       'op': 'remove'},
+                      {'path': '/instance_uuid',
+                       'op': 'remove'},
+                      {'path': '/device_rp_uuid',
+                       'op': 'remove'}]
+
+        self.assertTrue(
+            self.cloud.unbind_accelerator_request(
+                ARQ_DICT['uuid'], properties
+            )
+        )
+        self.assert_calls()
diff --git a/openstack/tests/unit/fixtures/accelerator.json b/openstack/tests/unit/fixtures/accelerator.json
new file mode 100644
index 000000000..bf2c04691
--- /dev/null
+++ b/openstack/tests/unit/fixtures/accelerator.json
@@ -0,0 +1,27 @@
+{
+    "versions": [
+        {
+            "id": "2.0",
+            "links": [
+                {
+                    "href": "/v2/",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://accelerator.example.com/api-ref/accelerator",
+                    "rel": "help"
+                }
+            ],
+            "max_version": "2.0",
+            "media-types": [
+                {
+                    "base": "application/json",
+                    "type": "application/vnd.openstack.accelerator-v1+json"
+                }
+            ],
+            "min_version": "2.0",
+            "status": "CURRENT",
+            "updated": "2019-09-01T00:00:00Z"
+        }
+    ]
+}
diff --git a/releasenotes/notes/add-cyborg-support-b9afca69f709c048.yaml b/releasenotes/notes/add-cyborg-support-b9afca69f709c048.yaml
new file mode 100644
index 000000000..9688a5e24
--- /dev/null
+++ b/releasenotes/notes/add-cyborg-support-b9afca69f709c048.yaml
@@ -0,0 +1,3 @@
+---
+features:
+  - Add support for Cyborg(accelerator)