Ditto for Images.

I'm guessing that the images service also uses marker-and-limit pagination. I'll have to
check when I'm less :airplane:.
diff --git a/openstack/compute/v2/images/client.go b/openstack/compute/v2/images/client.go
deleted file mode 100644
index 6322b9c..0000000
--- a/openstack/compute/v2/images/client.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package images
-
-import (
-	"github.com/rackspace/gophercloud"
-	identity "github.com/rackspace/gophercloud/openstack/identity/v2"
-)
-
-type Client struct {
-	endpoint  string
-	authority identity.AuthResults
-	options   gophercloud.AuthOptions
-}
-
-func NewClient(e string, a identity.AuthResults, ao gophercloud.AuthOptions) *Client {
-	return &Client{
-		endpoint:  e,
-		authority: a,
-		options:   ao,
-	}
-}
-
-func (c *Client) getListUrl() string {
-	return c.endpoint + "/images/detail"
-}
-
-func (c *Client) getListHeaders() (map[string]string, error) {
-	t, err := identity.GetToken(c.authority)
-	if err != nil {
-		return map[string]string{}, err
-	}
-
-	return map[string]string{
-		"X-Auth-Token": t.ID,
-	}, nil
-}
diff --git a/openstack/compute/v2/images/images.go b/openstack/compute/v2/images/images.go
index c881092..c4e838e 100644
--- a/openstack/compute/v2/images/images.go
+++ b/openstack/compute/v2/images/images.go
@@ -1,52 +1,38 @@
 package images
 
-import "github.com/mitchellh/mapstructure"
+import (
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud/pagination"
+)
 
 // Image is used for JSON (un)marshalling.
 // It provides a description of an OS image.
-//
-// The Id field contains the image's unique identifier.
-// For example, this identifier will be useful for specifying which operating system to install on a new server instance.
-//
-// The MinDisk and MinRam fields specify the minimum resources a server must provide to be able to install the image.
-//
-// The Name field provides a human-readable moniker for the OS image.
-//
-// The Progress and Status fields indicate image-creation status.
-// Any usable image will have 100% progress.
-//
-// The Updated field indicates the last time this image was changed.
 type Image struct {
-	Created  string
-	Id       string
-	MinDisk  int
-	MinRam   int
-	Name     string
+	// ID contains the image's unique identifier.
+	ID string
+
+	Created string
+
+	// MinDisk and MinRAM specify the minimum resources a server must provide to be able to install the image.
+	MinDisk int
+	MinRAM  int
+
+	// Name provides a human-readable moniker for the OS image.
+	Name string
+
+	// The Progress and Status fields indicate image-creation status.
+	// Any usable image will have 100% progress.
 	Progress int
 	Status   string
-	Updated  string
+
+	Updated string
 }
 
-func GetImages(lr ListResults) ([]Image, error) {
-	ia, ok := lr["images"]
-	if !ok {
-		return nil, ErrNotImplemented
-	}
-	ims := ia.([]interface{})
+// ExtractImages converts a page of List results into a slice of usable Image structs.
+func ExtractImages(page pagination.Page) ([]Image, error) {
+	casted := page.(ListResults).Body
+	var results []Image
 
-	images := make([]Image, len(ims))
-	for i, im := range ims {
-		imageObj := im.(map[string]interface{})
-		err := mapstructure.Decode(imageObj, &images[i])
-		if err != nil {
-			return images, err
-		}
-	}
-	return images, nil
-}
-
-func GetImage(ir ImageResults) (Image, error) {
-	image := Image{}
-	err := mapstructure.Decode(ir, &image)
-	return image, err
+	err := mapstructure.Decode(results, casted)
+	return results, err
 }
diff --git a/openstack/compute/v2/images/requests.go b/openstack/compute/v2/images/requests.go
index 79783c4..22c6e9b 100644
--- a/openstack/compute/v2/images/requests.go
+++ b/openstack/compute/v2/images/requests.go
@@ -1,26 +1,44 @@
 package images
 
 import (
-	"fmt"
-	"github.com/racker/perigee"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
 )
 
-var ErrNotImplemented = fmt.Errorf("Images functionality not implemented.")
+// ListResults contains a single page of results from a List operation.
+// Use ExtractImages to convert it into a slice of usable structs.
+type ListResults struct {
+	pagination.MarkerPageBase
+}
 
-type ListResults map[string]interface{}
-type ImageResults map[string]interface{}
-
-func List(c *Client) (ListResults, error) {
-	var lr ListResults
-
-	h, err := c.getListHeaders()
+// IsEmpty returns true if a page contains no Image results.
+func (page ListResults) IsEmpty() (bool, error) {
+	images, err := ExtractImages(page)
 	if err != nil {
-		return nil, err
+		return true, err
+	}
+	return len(images) == 0, nil
+}
+
+// LastMarker returns the ID of the final Image on the current page of ListResults.
+func (page ListResults) LastMarker() (string, error) {
+	images, err := ExtractImages(page)
+	if err != nil {
+		return "", err
+	}
+	if len(images) == 0 {
+		return "", nil
+	}
+	return images[len(images)-1].ID, nil
+}
+
+// List enumerates the available images.
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+	createPage := func(r pagination.LastHTTPResponse) pagination.Page {
+		p := ListResults{pagination.MarkerPageBase{LastHTTPResponse: r}}
+		p.MarkerPageBase.Owner = p
+		return p
 	}
 
-	err = perigee.Get(c.getListUrl(), perigee.Options{
-		Results:     &lr,
-		MoreHeaders: h,
-	})
-	return lr, err
+	return pagination.NewPager(client, getListURL(client), createPage)
 }
diff --git a/openstack/compute/v2/images/urls.go b/openstack/compute/v2/images/urls.go
new file mode 100644
index 0000000..0e40a4e
--- /dev/null
+++ b/openstack/compute/v2/images/urls.go
@@ -0,0 +1,7 @@
+package images
+
+import "github.com/rackspace/gophercloud"
+
+func getListURL(client *gophercloud.ServiceClient) string {
+	return client.ServiceURL("images", "detail")
+}