Write and test the Create call.
diff --git a/openstack/compute/v2/extensions/keypairs/fixtures.go b/openstack/compute/v2/extensions/keypairs/fixtures.go
index 2002b4a..878b3f3 100644
--- a/openstack/compute/v2/extensions/keypairs/fixtures.go
+++ b/openstack/compute/v2/extensions/keypairs/fixtures.go
@@ -131,9 +131,7 @@
 	th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "POST")
 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
-		th.TestJSONRequest(t, r, `
-			{ "keypair": { "name": "createdkey" } }
-		`)
+		th.TestJSONRequest(t, r, `{ "keypair": { "name": "createdkey" } }`)
 
 		w.Header().Add("Content-Type", "application/json")
 		fmt.Fprintf(w, CreateOutput)
diff --git a/openstack/compute/v2/extensions/keypairs/requests.go b/openstack/compute/v2/extensions/keypairs/requests.go
index 2e35a40..b676dd9 100644
--- a/openstack/compute/v2/extensions/keypairs/requests.go
+++ b/openstack/compute/v2/extensions/keypairs/requests.go
@@ -1,6 +1,8 @@
 package keypairs
 
 import (
+	"errors"
+
 	"github.com/racker/perigee"
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
@@ -13,6 +15,57 @@
 	})
 }
 
+// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
+// CreateOpts struct in this package does.
+type CreateOptsBuilder interface {
+	ToKeyPairCreateMap() (map[string]interface{}, error)
+}
+
+// CreateOpts species keypair creation or import parameters.
+type CreateOpts struct {
+	// Name [required] is a friendly name to refer to this KeyPair in other services.
+	Name string
+
+	// PublicKey [optional] is a pregenerated OpenSSH-formatted public key. If provided, this key
+	// will be imported and no new key will be created.
+	PublicKey string
+}
+
+// ToKeyPairCreateMap constructs a request body from CreateOpts.
+func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) {
+	if opts.Name == "" {
+		return nil, errors.New("Missing field required for keypair creation: Name")
+	}
+
+	keypair := make(map[string]interface{})
+	keypair["name"] = opts.Name
+	if opts.PublicKey != "" {
+		keypair["public_key"] = opts.PublicKey
+	}
+
+	return map[string]interface{}{"keypair": keypair}, nil
+}
+
+// Create requests the creation of a new keypair on the server, or to import a pre-existing
+// keypair.
+func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
+	var res CreateResult
+
+	reqBody, err := opts.ToKeyPairCreateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+
+	_, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
+		MoreHeaders: client.AuthenticatedHeaders(),
+		ReqBody:     reqBody,
+		Results:     &res.Body,
+		OkCodes:     []int{200},
+	})
+	return res
+}
+
 // Get returns public data about a previously uploaded KeyPair.
 func Get(client *gophercloud.ServiceClient, name string) GetResult {
 	var res GetResult
diff --git a/openstack/compute/v2/extensions/keypairs/requests_test.go b/openstack/compute/v2/extensions/keypairs/requests_test.go
index e69bcdb..8a9896f 100644
--- a/openstack/compute/v2/extensions/keypairs/requests_test.go
+++ b/openstack/compute/v2/extensions/keypairs/requests_test.go
@@ -26,6 +26,18 @@
 	th.CheckEquals(t, 1, count)
 }
 
+func TestCreate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleCreateSuccessfully(t)
+
+	actual, err := Create(client.ServiceClient(), CreateOpts{
+		Name: "createdkey",
+	}).Extract()
+	th.AssertNoErr(t, err)
+	th.CheckDeepEquals(t, &CreatedKeyPair, actual)
+}
+
 func TestGet(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()