diff --git a/src/service/map_request.rs b/src/service/map_request.rs
new file mode 100644
index 00000000..716fcf1f
--- /dev/null
+++ b/src/service/map_request.rs
@@ -0,0 +1,141 @@
+use std::marker;
+
+use futures::{Async, Future, Poll};
+use {NewService, Service};
+
+/// `MapReq` service combinator
+pub struct MapReq<A, F, R> {
+    a: A,
+    f: F,
+    r: marker::PhantomData<R>,
+}
+
+impl<A, F, R> MapReq<A, F, R>
+where
+    A: Service,
+    F: Fn(R) -> A::Request,
+{
+    /// Create new `MapReq` combinator
+    pub fn new(a: A, f: F) -> Self {
+        Self {
+            a,
+            f,
+            r: marker::PhantomData,
+        }
+    }
+}
+
+impl<A, F, R> Service for MapReq<A, F, R>
+where
+    A: Service,
+    F: Fn(R) -> A::Request,
+    F: Clone,
+{
+    type Request = R;
+    type Response = A::Response;
+    type Error = A::Error;
+    type Future = A::Future;
+
+    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
+        self.a.poll_ready()
+    }
+
+    fn call(&mut self, req: Self::Request) -> Self::Future {
+        self.a.call((self.f)(req))
+    }
+}
+
+/// `MapReqNewService` new service combinator
+pub struct MapReqNewService<A, F, R> {
+    a: A,
+    f: F,
+    r: marker::PhantomData<R>,
+}
+
+impl<A, F, R> MapReqNewService<A, F, R>
+where
+    A: NewService,
+    F: Fn(R) -> A::Request,
+{
+    /// Create new `MapReq` new service instance
+    pub fn new(a: A, f: F) -> Self {
+        Self {
+            a,
+            f,
+            r: marker::PhantomData,
+        }
+    }
+}
+
+impl<A, F, R> Clone for MapReqNewService<A, F, R>
+where
+    A: NewService + Clone,
+    F: Fn(R) -> A::Request + Clone,
+{
+    fn clone(&self) -> Self {
+        Self {
+            a: self.a.clone(),
+            f: self.f.clone(),
+            r: marker::PhantomData,
+        }
+    }
+}
+
+impl<A, F, R> NewService for MapReqNewService<A, F, R>
+where
+    A: NewService,
+    F: Fn(R) -> A::Request + Clone,
+{
+    type Request = R;
+    type Response = A::Response;
+    type Error = A::Error;
+    type Service = MapReq<A::Service, F, R>;
+
+    type InitError = A::InitError;
+    type Future = MapReqNewServiceFuture<A, F, R>;
+
+    fn new_service(&self) -> Self::Future {
+        MapReqNewServiceFuture::new(self.a.new_service(), self.f.clone())
+    }
+}
+
+pub struct MapReqNewServiceFuture<A, F, R>
+where
+    A: NewService,
+    F: Fn(R) -> A::Request,
+{
+    fut: A::Future,
+    f: Option<F>,
+    r: marker::PhantomData<R>,
+}
+
+impl<A, F, R> MapReqNewServiceFuture<A, F, R>
+where
+    A: NewService,
+    F: Fn(R) -> A::Request,
+{
+    fn new(fut: A::Future, f: F) -> Self {
+        MapReqNewServiceFuture {
+            f: Some(f),
+            fut,
+            r: marker::PhantomData,
+        }
+    }
+}
+
+impl<A, F, R> Future for MapReqNewServiceFuture<A, F, R>
+where
+    A: NewService,
+    F: Fn(R) -> A::Request,
+{
+    type Item = MapReq<A::Service, F, R>;
+    type Error = A::InitError;
+
+    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+        if let Async::Ready(service) = self.fut.poll()? {
+            Ok(Async::Ready(MapReq::new(service, self.f.take().unwrap())))
+        } else {
+            Ok(Async::NotReady)
+        }
+    }
+}
diff --git a/src/service/mod.rs b/src/service/mod.rs
index 8c4e3666..f85dc600 100644
--- a/src/service/mod.rs
+++ b/src/service/mod.rs
@@ -7,6 +7,7 @@ mod fn_state_service;
 mod map;
 mod map_err;
 mod map_init_err;
+mod map_request;
 mod partial;
 
 pub use self::and_then::{AndThen, AndThenNewService};
@@ -15,6 +16,7 @@ pub use self::fn_state_service::{FnStateNewService, FnStateService};
 pub use self::map::{Map, MapNewService};
 pub use self::map_err::{MapErr, MapErrNewService};
 pub use self::map_init_err::MapInitErr;
+pub use self::map_request::{MapReq, MapReqNewService};
 pub use self::partial::{Partial, PartialNewService};
 
 pub trait ServiceExt: Service {
@@ -74,6 +76,14 @@ pub trait NewServiceExt: NewService {
         MapErrNewService::new(self, f)
     }
 
+    fn map_request<F, R>(self, f: F) -> MapReqNewService<Self, F, R>
+    where
+        Self: Sized,
+        F: Fn(R) -> Self::Request,
+    {
+        MapReqNewService::new(self, f)
+    }
+
     fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, E>
     where
         Self: Sized,