diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index 850734a..28b861f 100644
*** a/src/interfaces/libpq/exports.txt
--- b/src/interfaces/libpq/exports.txt
*************** PQclosePrepared           188
*** 191,193 ****
--- 191,194 ----
  PQclosePortal             189
  PQsendClosePrepared       190
  PQsendClosePortal         191
+ PQchangePassword          192
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 912aa14..3ee67ba 100644
*** a/src/interfaces/libpq/fe-auth.c
--- b/src/interfaces/libpq/fe-auth.c
*************** PQencryptPasswordConn(PGconn *conn, cons
*** 1372,1374 ****
--- 1372,1463 ----
  
  	return crypt_pwd;
  }
+ 
+ /*
+  * PQchangePassword -- exported routine to change a password
+  *
+  * This is intended to be used by client applications that wish to
+  * change the password for a user.  The password is not sent in
+  * cleartext because it is encrypted on the client side. This is
+  * good because it ensures the cleartext password is never known by
+  * the server, and therefore won't end up in logs, pg_stat displays,
+  * etc. We export the function so that clients won't be dependent
+  * on the implementation specific details with respect to how the
+  * server changes passwords.
+  *
+  * Arguments are a connection object, the cleartext password, the SQL
+  * name of the user it is for, and a string indicating the algorithm to
+  * use for encrypting the password.  If algorithm is NULL,
+  * PQencryptPasswordConn() queries the server for the current
+  * 'password_encryption' value. If you wish to avoid that, e.g. to avoid
+  * blocking, you can execute 'show password_encryption' yourself before
+  * calling this function, and pass it as the algorithm.
+  *
+  * Return value is a boolean, true for success. On error, an error message
+  * is stored in the connection object, and returns false.
+  */
+ bool
+ PQchangePassword(PGconn *conn, const char *passwd, const char *user,
+ 				 const char *algorithm)
+ {
+ 	char		   *encrypted_password = NULL;
+ 	PQExpBufferData buf;
+ 	bool			success = true;
+ 
+ 	encrypted_password = PQencryptPasswordConn(conn, passwd, user, algorithm);
+ 
+ 	if (!encrypted_password)
+ 	{
+ 		/* PQencryptPasswordConn() already registered the error */
+ 		success = false;
+ 	}
+ 	else
+ 	{
+ 		char	   *fmtpw = NULL;
+ 
+ 		fmtpw = PQescapeLiteral(conn, encrypted_password,
+ 								strlen(encrypted_password));
+ 
+ 		/* no longer needed, so clean up now */
+ 		PQfreemem(encrypted_password);
+ 
+ 		if (!fmtpw)
+ 		{
+ 			/* PQescapeLiteral() already registered the error */
+ 			success = false;
+ 		}
+ 		else
+ 		{
+ 			char	   *fmtuser = NULL;
+ 
+ 			fmtuser = PQescapeIdentifier(conn, user, strlen(user));
+ 			if (!fmtuser)
+ 			{
+ 				/* PQescapeIdentifier() already registered the error */
+ 				success = false;
+ 				PQfreemem(fmtpw);
+ 			}
+ 			else
+ 			{
+ 				PGresult   *res;
+ 
+ 				initPQExpBuffer(&buf);
+ 				printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD %s",
+ 								  fmtuser, fmtpw);
+ 
+ 				res = PQexec(conn, buf.data);
+ 				if (!res)
+ 					success = false;
+ 				else
+ 					PQclear(res);
+ 
+ 				/* clean up */
+ 				termPQExpBuffer(&buf);
+ 				PQfreemem(fmtuser);
+ 				PQfreemem(fmtpw);
+ 			}
+ 		}
+ 	}
+ 
+ 	return success;
+ }
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 97762d5..f6e7207 100644
*** a/src/interfaces/libpq/libpq-fe.h
--- b/src/interfaces/libpq/libpq-fe.h
*************** extern int	PQenv2encoding(void);
*** 659,664 ****
--- 659,665 ----
  
  extern char *PQencryptPassword(const char *passwd, const char *user);
  extern char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm);
+ extern bool PQchangePassword(PGconn *conn, const char *passwd, const char *user, const char *algorithm);
  
  /* === in encnames.c === */
  
